diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c1c4128..8ae5483 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ on: - main env: - VERSION_NUMBER: 'v1.2.3' + VERSION_NUMBER: 'v1.2.4' DOCKERHUB_REGISTRY_NAME: 'digitalghostdev/poke-cli' AWS_REGION: 'us-west-2' diff --git a/.goreleaser.yaml b/.goreleaser.yaml index dd99b6c..71b1886 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -14,7 +14,7 @@ builds: - windows - darwin ldflags: - - -s -w -X main.version=v1.2.3 + - -s -w -X main.version=v1.2.4 archives: - format: tar.gz diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index cecd4df..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,567 +0,0 @@ -# Change Log -This change log provides version history for tags prior to `v1.0.0` - -Due to the lack of control over dates when creating a release, I've decided to move the change history per tag prior to `v1.0.0` to a `CHANGELOG.md` file. - -Some previous releases had their dates screwed up and without a way to backdate a release like [GitLab](https://docs.gitlab.com/api/releases/#update-a-release), the release history is out of date. -If GitHub allows backdating in the future, I will recreate these releases with their tag date. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -* **MAJOR:** Any changes to the backend infrastructure that requires new methods of moving data that won't work with the previous architecture, mainly with the addition of new databases or data sources. -* **MINOR:** Any changes to the Streamlit dashboard that adds a new interaction/feature or removal of one. -* **PATCH:** Any changes that fix bugs, typos or small edits. - -# Version History - -## v0.12.2 -_March 7th, 2024_ - -### Changed -* Changed location of style definitions and structs to their own respective packages for scalability. [(#106)](https://github.com/digitalghost-dev/poke-cli/issues/106) - -### Details -* **Commit Change Log:** [v0.12.1 > v0.12.2](https://github.com/digitalghost-dev/poke-cli/compare/v0.12.1...v0.12.2) -* **Associated PRs:** [#107](https://github.com/digitalghost-dev/poke-cli/pull/107) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.12.2) - ---- - -## v0.12.1 -_March 4th, 2025_ - -### Changed -* Changed help menus for better clarity. [(#103)](https://github.com/digitalghost-dev/poke-cli/issues/103) - -### Fixed -* Fixed error handling issue with `ability` command. [(#104)](https://github.com/digitalghost-dev/poke-cli/issues/104) - -### Details -* **Commit Change Log:** [v0.12.0 > v0.12.1](https://github.com/digitalghost-dev/poke-cli/compare/v0.12.0...v0.12.1) -* **Associated PRs:** [#105](https://github.com/digitalghost-dev/poke-cli/pull/105) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.12.1) - ---- - -## v0.12.0 -_February 2nd, 2025_ - -### Added -* Added new `ability` command. Get details about a specific ability. [(#101)](https://github.com/digitalghost-dev/poke-cli/issues/101) - - ```bash - poke-cli ability unware - - # output - Unaware - Effect: Ignores other Pokémon's stat modifiers for damage and accuracy calculation. - ``` - -* Added `-p | --pokemon` flag to the `ability` command. [(#99)](https://github.com/digitalghost-dev/poke-cli/issues/99) - - ```bash - poke-cli ability stench --pokemon - - Stench - Effect: Has a 10% chance of making target Pokémon flinch with each hit. - - Pokemon with Stench - - 1. Gloom 2. Grimer 3. Muk - 4. Koffing 5. Weezing 6. Stunky - 7. Skuntank 8. Trubbish 9. Garbodor - 10. Garbodor-Gmax - ``` - -* Added better error messaging to API call functions. [(#98)](https://github.com/digitalghost-dev/poke-cli/issues/98) -* Added a designated file for holding style variables to the `flags/` directory. [(#100)](https://github.com/digitalghost-dev/poke-cli/issues/100) - -### Details -* **Commit Change Log:** [v0.11.1 > v0.12.0](https://github.com/digitalghost-dev/poke-cli/compare/v0.11.1...v0.12.0) -* **Associated PRs:** [#102](https://github.com/digitalghost-dev/poke-cli/pull/102) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.12.0) - ---- - -## v0.11.1 -_January 13th, 2024_ - -### Fixed -* Fix issue of using the `--image | -i` flag without an argument but with a `=` at the end. [(#96)](https://github.com/digitalghost-dev/poke-cli/issues/96) - * For example, running: `poke-cli pokemon cacturne --image=` would not error out the program or print an image. Running this in `v0.11.1` returns an error. - -### Details -* **Commit Change Log:** [v0.11.0 > v0.11.1](https://github.com/digitalghost-dev/poke-cli/compare/v0.11.0...v0.11.1) -* **Associated PRs:** [#97](https://github.com/digitalghost-dev/poke-cli/pull/97) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.11.1) - ---- - -## v0.11.0 -_January 6th, 2024_ - -### Added -* Added a new flag for generating Pokémon sprites with options for different sizes. [(#93)](https://github.com/digitalghost-dev/poke-cli/issues/93) - * _Example:_ `poke-cli pokemon gengar -i=sm` - -### Details -* **Commit Change Log:** [v0.10.0 > v0.11.0](https://github.com/digitalghost-dev/poke-cli/compare/v0.10.0...v0.11.0) -* **Associated PRs:** [#94](https://github.com/digitalghost-dev/poke-cli/pull/94) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.11.0) - -**Contributions** -* @ancientcatz - replaced simpleicons image with local `.svg` file. - ---- - -## v0.10.0 -_December 26th, 2024_ - -### Added -* Added total base points to output of the `-s | --stats` flag. [(#87)](https://github.com/digitalghost-dev/poke-cli/issues/87) -* Added a navigation menu while selecting a type. [(#90)](https://github.com/digitalghost-dev/poke-cli/issues/90) -* Added a `natures` command that prints out a table of all natures and affected stats. [(#91)](https://github.com/digitalghost-dev/poke-cli/issues/91) - -### Details -* **Commit Change Log:** [v0.9.3 > v0.10.0](https://github.com/digitalghost-dev/poke-cli/compare/v0.9.3...v0.10.0) -* **Associated PRs:** [#92](https://github.com/digitalghost-dev/poke-cli/pull/92) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.10.0) - ---- - -## v0.9.3 -_December 16th, 2024_ - -### Fixed -* Fixed spacing in damage table when selecting type with the `types` command. This will help the chart fit on smaller terminal windows. [(#88)](https://github.com/digitalghost-dev/poke-cli/issues/88) - -### Details -* **Commit Change Log:** [v0.9.2 > v0.9.3](https://github.com/digitalghost-dev/poke-cli/compare/v0.9.2...v0.9.3) -* **Associated PRs:** [#89]((https://github.com/digitalghost-dev/poke-cli/pull/89) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.9.3) - ---- - -## v0.9.2 -_December 14th, 2024_ - -### Fixed -* Fixed various string formatting, specifically with Pokémon names and abilities using a hyphen. [(#85)]((https://github.com/digitalghost-dev/poke-cli/issues/85)) - -### Details -* **Commit Change Log:** [v0.9.1 > v0.9.2](https://github.com/digitalghost-dev/poke-cli/compare/v0.9.1...v0.9.2) -* **Associated PRs:** [#86](https://github.com/digitalghost-dev/poke-cli/pull/86) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.9.2) - ---- - -## v0.9.1 -_December 8th, 2024_ - -### Fixed -* Fixed error message outputs to use a `lipgloss` border, specifically when using an empty flag (`poke-cli pokemon -s --`) and when mistyping a Pokémon's name. [(#83)](https://github.com/digitalghost-dev/poke-cli/issues/83) - -### Details -* **Commit Change Log:** [v0.9.0 > v0.9.1](https://github.com/digitalghost-dev/poke-cli/compare/v0.9.0...v0.9.1) -* **Associated PRs:** [#84](https://github.com/digitalghost-dev/poke-cli/pull/84) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.9.1) - ---- - -## v0.9.0 -_December 6th, 2024_ - -### Added -* Added a new flag `-v | --version` to check the current version of the tool. [(#78)](https://github.com/digitalghost-dev/poke-cli/issues/78) -* Added the number of moves belonging to a specified type when using the `types` command. [(#79)](https://github.com/digitalghost-dev/poke-cli/issues/79) - -### Security -* Secured against G107 (CWE-88). [(#80)](https://github.com/digitalghost-dev/poke-cli/issues/80) - -### Details -* **Commit Change Log:** [v0.8.0 > v0.9.0](https://github.com/digitalghost-dev/poke-cli/compare/v0.8.0...v0.9.0) -* **Associated PRs:** [#81](https://github.com/digitalghost-dev/poke-cli/pull/81) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.9.0) - ---- - -## v0.8.0 -_November 27th, 2024_ - -### Added -* Added a new flag `-s | --stats` to the `pokemon` command to view a Pokémon's base stats. [(#74)](https://github.com/digitalghost-dev/poke-cli/issues/74) -* Added a function to print out the header for any flag option under the `pokemon` command, reducing redundancy. [(#75)](https://github.com/digitalghost-dev/poke-cli/issues/75) -* Added metrics to the `pokemon` command that includes height and weight. [(#76)](https://github.com/digitalghost-dev/poke-cli/issues/76) - -### Details -* **Commit Change Log:** [v0.7.2 > v0.8.0](https://github.com/digitalghost-dev/poke-cli/compare/v0.7.2...v0.8.0) -* **Associated PRs:** [#77](https://github.com/digitalghost-dev/poke-cli/pull/77) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.8.0) - ---- - -## v0.7.2 -_November 21st, 2024_ - -### Changed -* Changed location of `getTypeColor()` function to `cmd/styles.go`. [(#71)]((https://github.com/digitalghost-dev/poke-cli/issues/71) - -### Removed -* Removed `httpGet` variable from `connections/connection.go`. [(#72)](https://github.com/digitalghost-dev/poke-cli/issues/72) - - -### Details -* **Commit Change Log:** [v0.7.1 > v0.7.2](https://github.com/digitalghost-dev/poke-cli/compare/v0.7.1...v0.7.2) -* **Associated PRs:** [#73](https://github.com/digitalghost-dev/poke-cli/pull/73) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.7.2) - ---- - -## v0.7.1 -_November 12th, 2024_ - -### Added -* Added a helper method that helps reduce redundancy by passing it into each command's argument validator. [(#69)](https://github.com/digitalghost-dev/poke-cli/issues/69) - -### Changed -* Changed the help menus for the current commands by simplifying the text and verbiage. [(#67)](https://github.com/digitalghost-dev/poke-cli/issues/67) -* Changed the `pokemon` and `types` help menu to include the `-h, --help` flag. [(#65)](https://github.com/digitalghost-dev/poke-cli/issues/65) - -### Fixed -* Fixed a bug where misspelling a Pokémon's name would error out but still would run the rest of the program with blank data. [(#68)](https://github.com/digitalghost-dev/poke-cli/issues/68) -* Fixed a bug when using the help flag on either the `pokemon` or `types` command; the program defaults to using the `mainFlagSet.Usage()` menu instead of the help menu for each command. [(#64)](https://github.com/digitalghost-dev/poke-cli/issues/64) - -### Details -* **Commit Change Log:** [v0.7.0 > v0.7.1](https://github.com/digitalghost-dev/poke-cli/compare/v0.7.0...v0.7.1) -* **Associated PRs:** [#70](https://github.com/digitalghost-dev/poke-cli/pull/70) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.7.1) - ---- - -## v0.7.0 -_November 2nd, 2024_ - -### Added -* Added a damage chart to `poke-cli types`. It shows a list of the selected type's weaknesses, resistances, immunities, and damage to other types using a [BubbleTea](https://github.com/charmbracelet/bubbletea/tree/main) list. [(#62)](https://github.com/digitalghost-dev/poke-cli/issues/62) - -### Changed -* Changed the `ApiCallSetup()` function in `connections/connection.go` to return `fmt.Errorf()` instead of various `fmt.Println()` and `log.Fatalf()` uses which made testing the file difficult. Now, testing coverage for the `connections` package has increased to over 85%. [(#66)](https://github.com/digitalghost-dev/poke-cli/issues/66) - -### Details -* **Commit Change Log:** [v0.6.5 > v0.7.0](https://github.com/digitalghost-dev/poke-cli/compare/v0.6.5...v0.7.0) -* **Associated PRs:** [#63](https://github.com/digitalghost-dev/poke-cli/pull/63) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.7.0) - ---- - -## v0.6.5 -_October 29th, 2024_ - -### Changed -* Changed `cli.go` to provide test coverage opportunities and better maintainability. Moved logic out of `main()` and into a separate `runCLI` function. [(#58)]((https://github.com/digitalghost-dev/poke-cli/issues/58)) - -### Fixed -* Fixed expression always equating to `false`. [(#57)](https://github.com/digitalghost-dev/poke-cli/issues/57) - -### Details -* **Commit Change Log:** [v0.6.4 > v0.6.5](https://github.com/digitalghost-dev/poke-cli/compare/v0.6.4...v0.6.5) -* **Associated PRs:** [#59](https://github.com/digitalghost-dev/poke-cli/pull/59) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.6.5) - ---- - -## v0.6.4 -_October 26th, 2024_ - -### Changed -* Changed output to include color when printing out a type for the `poke-cli types` command. [(#55)](https://github.com/digitalghost-dev/poke-cli/issues/55) - -### Details -* **Commit Change Log:** [v0.6.3 > v0.6.4](https://github.com/digitalghost-dev/poke-cli/compare/v0.6.3...v0.6.4) -* **Associated PRs:** [#56](https://github.com/digitalghost-dev/poke-cli/pull/55) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.6.4) - ---- - -## v0.6.3 -_October 20th, 2024_ - -### Changed -* Changed code in `types.go` for better organization. [(#51)](https://github.com/digitalghost-dev/poke-cli/issues/51) -* Changed message when using a non-available command. [(#52)](https://github.com/digitalghost-dev/poke-cli/issues/52) - * Previously, only a generic `Unknown command` error would show when not using an available commanded. -* Changed location of `lipgloss` variables to their own file since they are used multiple times throughout the `cmd` package. [(#53)](https://github.com/digitalghost-dev/poke-cli/issues/53) - -### Details -* **Commit Change Log:** [v0.6.2 > v0.6.3](https://github.com/digitalghost-dev/poke-cli/compare/v0.6.2...v0.6.3) -* **Associated PRs:** [#54](https://github.com/digitalghost-dev/poke-cli/pull/54) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.6.3) - ---- - -## v0.6.2 -_October 7th, 2024_ - -### Changed -* Changed the location of checking for an `-h` or `--help` flag from `cmd/types.go` to its intended place in `cmd/validateargs.go` where the rest of the validation takes place. (#48) - -### Fixed -* Fixed not directly handling when the 3rd argument is `-h` or `--help` after using `poke-cli types`. [(#49)](https://github.com/digitalghost-dev/poke-cli/issues/49) -* Fixed `os.Exit(0)` being called unconditionally, which interrupted tests. Now, the program can exit and not affect tests. [(#49)](https://github.com/digitalghost-dev/poke-cli/issues/49) - -### Details -* **Commit Change Log:** [v0.6.1 > v0.6.2](https://github.com/digitalghost-dev/poke-cli/compare/v0.6.1...v0.6.2) -* **Associated PRs:** [#50](https://github.com/digitalghost-dev/poke-cli/pull/50) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.6.2) - ---- - -## v0.6.1 -_October 5th, 2024_ - -### Changed -* Changed code for better organization by moving the results of table selection when using `poke-cli types` to a separate helper method. [(#42)](https://github.com/digitalghost-dev/poke-cli/issues/42) -* Changed the usage of `fmt.Errorf()` by inputting a styled error message to improve readability and easier future changes. [(#45)](https://github.com/digitalghost-dev/poke-cli/issues/45) - * For example: - ```go - // new - if len(args) < 3 { - errMessage := errorBorder.Render(errorColor.Render("Error!"), "some text...") - return fmt.Errorf("%s", errMessage) - } - - // old - if len(args) < 3 { - return fmt.Errorf(errorBorder.Render(errorColor.Render("Error!"), "some text...")) - } - ``` - -### Fixed -* Fixed an issue where the `-h` or `--help` flag for `poke-cli types` would incorrectly return an error (`fmt.Errorf`) instead of exiting gracefully. Now, using the `-h` or `--help` flags correctly stops the program and displays the help menu. [(#44)](https://github.com/digitalghost-dev/poke-cli/issues/44) - -### Details -* **Commit Change Log:** [v0.6.0 > v0.6.1](https://github.com/digitalghost-dev/poke-cli/compare/v0.6.0...v0.6.1) -* **Associated PRs:** [#47](https://github.com/digitalghost-dev/poke-cli/pull/47) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.6.1) - ---- - -## v0.6.0 -_September 30th, 2024_ - -### Added -* Added a new `types` command. (#41) - * This command can be used to get details about a specific typing. - * For example: - ``` - poke-cli types - ``` -* Added a new `cmd/validateargs.go` file that will validate each commands given arguments. [(#39)](https://github.com/digitalghost-dev/poke-cli/issues/39) - -### Changed -* Changed the program's help menu to include the new `types` command. [(#37)](https://github.com/digitalghost-dev/poke-cli/issues/37) - -### Fixed -* Fixed the argument check when running only the program name to not display the program's help menu. [(#38)](https://github.com/digitalghost-dev/poke-cli/issues/38) - -### Details -* **Commit Change Log:** [v0.5.2 > v0.6.0](https://github.com/digitalghost-dev/poke-cli/compare/v0.5.2...v0.6.0) -* **Associated PRs:** [#40](https://github.com/digitalghost-dev/poke-cli/pull/40) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.6.0) - ---- - -## v0.5.2 -_September 21st, 2024_ - -### Changed -* Changed the main help menu to use a `lipgloss` border. [(#34)](https://github.com/digitalghost-dev/poke-cli/issues/34) - -### Fixed -* Fixed spacing/tabbing issues with `poke-cli pokemon -h` help menu. [(#35)](https://github.com/digitalghost-dev/poke-cli/issues/35) - -### Details -* **Commit Change Log:** [v0.5.1 > v0.5.2](https://github.com/digitalghost-dev/poke-cli/compare/v0.5.1...v0.5.2) -* **Associated PRs:** [#36](https://github.com/digitalghost-dev/poke-cli/pull/36) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.5.2) - -___ - -## v0.5.1 -_September 9th, 2024_ - -### Changed -* Changed code for better organization and output. [(#31)](https://github.com/digitalghost-dev/poke-cli/issues/31) -* Changed help menu output when using `-h` or `--help` after declaring a Pokémon's name. [(#32)](https://github.com/digitalghost-dev/poke-cli/issues/32) - -Example: -`poke-cli pokemon lycanroc --help` - -Output: -``` - poke-cli pokemon [flags] - - FLAGS: - -a, --abilities Prints out the Pokémon's abilities. - -t, --types Prints out the Pokémon's typing. -``` - -### Details -* **Commit Change Log:** [v0.5.0 > v0.5.1](https://github.com/digitalghost-dev/poke-cli/compare/v0.5.0...v0.5.1) -* **Associated PRs:** [#33](https://github.com/digitalghost-dev/poke-cli/pull/33) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.5.1) - ---- - -## v0.5.0 -_August 27th, 2024_ - -### Changed -* Changed the way the tool is used by requiring the name of the API endpoint in `os.Args`. This change will allow the tool to use different endpoint in future updates. [(#26)](https://github.com/digitalghost-dev/poke-cli/issues/26) -* Changed the `subcommands/` directory to `cmd/` to better fit the tool's architecture. [(#29)](https://github.com/digitalghost-dev/poke-cli/issues/29) - -**Example:** -```bash -$ poke-cli pokemon cacturne -t -a - -# future example -$ poke-cli types -``` - -### Details -* **Commit Change Log:** [v0.4.0 > v0.5.0](https://github.com/digitalghost-dev/poke-cli/compare/v0.4.0...v0.5.0) -* **Associated PRs:** [#30](https://github.com/digitalghost-dev/poke-cli/pull/30) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.5.0) - ---- - -## v0.4.0 -_August 1st, 2024_ - -### Added -* Added a flag to check the latest Docker image tag on DockerHub and the latest release tag on GitHub. [(#24)](https://github.com/digitalghost-dev/poke-cli/issues/24) - * `-l` or `--latest` - -**Example:** -```bash -[21:15:16] ~ $ poke-cli -l -Latest Docker image version: v0.4.0 -Latest release tag: v0.4.0 -``` - -### Details -* **Commit Change Log:** [v0.3.2 > v0.4.0](https://github.com/digitalghost-dev/poke-cli/compare/v0.3.2...v0.4.0) -* **Associated PRs:** [#25](https://github.com/digitalghost-dev/poke-cli/pull/25) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.4.0) - ---- - -## v0.3.2 -_July 18th, 2024_ - -### Added -* Added short aliases for current flags and will include in future flags. [(#20)](https://github.com/digitalghost-dev/poke-cli/issues/20) - * `--abilities` = `-a` - * `--types` = `-t` - -### Changed -* Changed the way a Pokémon's hidden ability in the output. [(#21)](https://github.com/digitalghost-dev/poke-cli/issues/21) - -### Details -* **Commit Change Log:** [v0.3.1 > v0.3.2](https://github.com/digitalghost-dev/poke-cli/compare/v0.3.1...v0.3.2) -* **Associated PRs:** [#22](https://github.com/digitalghost-dev/poke-cli/pull/22) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.3.2) - ---- - -## v0.3.1 -_July 12th, 2024_ - -### Changed -* Changed logic behind validating arguments given to the command. [(#16)](https://github.com/digitalghost-dev/poke-cli/issues/16) - -### Fixed -* Fixed tests to verify output with new `--abilities` flag added in `v0.3.0`. [(#15)](https://github.com/digitalghost-dev/poke-cli/issues/15) -* Fixed `--help` message to display to information about the `--abilities` flag. [(#17)](https://github.com/digitalghost-dev/poke-cli/issues/17) - -### Details -* **Commit Change Log:** [v0.3.0 > v0.3.1](https://github.com/digitalghost-dev/poke-cli/compare/v0.3.0...v0.3.1) -* **Associated PRs:** [#18](https://github.com/digitalghost-dev/poke-cli/pull/18) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.3.1) - ---- - -## v0.3.0 -_July 7th, 2024_ - -### Added -* Added a new flag `--abilities` that prints out the Pokémon's ability or abilities. [(#13)](https://github.com/digitalghost-dev/poke-cli/issues/13) - -Example: -``` -poke-cli ambipom --abilities -``` - -output: - -![image](https://github.com/digitalghost-dev/poke-cli/assets/86637723/71a79d1f-9b6c-4245-873f-b04cebb52e0d) - -### Details -* **Commit Change Log:** [v0.2.0 > v0.3.0](https://github.com/digitalghost-dev/poke-cli/compare/v0.2.0...v0.3.0) -* **Associated PRs:** [#14](https://github.com/digitalghost-dev/poke-cli/pull/14) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.3.0) - ---- - -## v0.2.0 -_June 8th, 2024_ - -### Added -- Added the Pokémon's national dex number to output. [(#8)](https://github.com/digitalghost-dev/poke-cli/issues/8) -- Added a `colorMap` with all colors based on the 18 types. When declaring the `--types` flag after a Pokémon's name, the printed types will be presented in their respective color. Colors are based on the type chart from [pokemondb.net](https://pokemondb.net/type). [(#9)](https://github.com/digitalghost-dev/poke-cli/issues/9) -- Added `strings.ToLower()` to allow mixed-case typing of a Pokémon's name. [(#10)](https://github.com/digitalghost-dev/poke-cli/issues/10) -- Added a header when declaring the `--types` flag for a better organized output. [(#11)](https://github.com/digitalghost-dev/poke-cli/issues/11) - -### Details -* **Commit Change Log:** [v0.1.1 > v0.2.0](https://github.com/digitalghost-dev/poke-cli/compare/v0.1.1...v0.2.0) -* **Associated PRs:** [#12](https://github.com/digitalghost-dev/poke-cli/pull/12) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.2.0) - ---- - -## v0.1.1 -_June 4th, 2024_ - -### Changed -- Moved the logic for the `--types` flag under the `TypesFlag()` function instead of it being handing under the `connections/connection.go` file. [(#5)](https://github.com/digitalghost-dev/poke-cli/issues/5) -- Moved the `type Pokemon struct` outside of functions and created a single `struct` instead of breaking it up per function. [(#6)](https://github.com/digitalghost-dev/poke-cli/issues/6) - -### Details -* **Commit Change Log:** [v0.1.0. > v0.1.1](https://github.com/digitalghost-dev/poke-cli/compare/v0.1.0...v0.1.1) -* **Associated PRs:** [#7](https://github.com/digitalghost-dev/poke-cli/pull/7) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.1.1) -* ---- - -## v0.1.0 -_June 1st, 2024_ - -### Added -- Added a connections file that'll hold all the logic for calling the API. [(#1)](https://github.com/digitalghost-dev/poke-cli/issues/1) -- Added a flagset to be used with `pokemon` subcommand. [(#2)](https://github.com/digitalghost-dev/poke-cli/issues/2) -- Added a subcommand that takes `os.Args[1]` for use after calling the tool. [(#3)](https://github.com/digitalghost-dev/poke-cli/issues/3) - - For example: -```bash -~ $ poke-cli bulbasaur --types - -# output: -> Selected Pokémon: Bulbasaur -> Type 1: grass -> Type 2: poison -``` - -### Details -* [Full Changelog](https://github.com/digitalghost-dev/poke-cli/commits/v0.1.0) -* **Associated PRs:** [#4](https://github.com/digitalghost-dev/poke-cli/pull/4) -* [Tag](https://github.com/digitalghost-dev/poke-cli/releases/tag/v0.1.0) \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index feb68cb..f74431f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ RUN go mod download COPY . . -RUN go build -ldflags "-X main.version=v1.2.3" -o poke-cli . +RUN go build -ldflags "-X main.version=v1.2.4" -o poke-cli . # build 2 FROM --platform=$BUILDPLATFORM alpine:latest diff --git a/README.md b/README.md index c181cf7..e35dd07 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ pokemon-logo

Pokémon CLI

version-label - docker-image-size + docker-image-size ci-status-badge
@@ -76,11 +76,11 @@ View future plans in the [Roadmap](#roadmap) section. 3. Choose how to interact with the container: * Run a single command and exit: ```bash - docker run --rm -it digitalghostdev/poke-cli:v1.2.3 [subcommand] flag] + docker run --rm -it digitalghostdev/poke-cli:v1.2.4 [subcommand] flag] ``` * Enter the container and use its shell: ```bash - docker run --rm -it --name poke-cli --entrypoint /bin/sh digitalghostdev/poke-cli:v1.2.3 -c "cd /app && exec sh" + docker run --rm -it --name poke-cli --entrypoint /bin/sh digitalghostdev/poke-cli:v1.2.4 -c "cd /app && exec sh" # placed into the /app directory, run the program with './poke-cli' # example: ./poke-cli ability swift-swim ``` diff --git a/cli.go b/cli.go index bea01c3..5972575 100644 --- a/cli.go +++ b/cli.go @@ -3,16 +3,18 @@ package main import ( "flag" "fmt" - "github.com/digitalghost-dev/poke-cli/cmd" "github.com/digitalghost-dev/poke-cli/cmd/ability" "github.com/digitalghost-dev/poke-cli/cmd/move" "github.com/digitalghost-dev/poke-cli/cmd/natures" + "github.com/digitalghost-dev/poke-cli/cmd/pokemon" "github.com/digitalghost-dev/poke-cli/cmd/search" "github.com/digitalghost-dev/poke-cli/cmd/types" + "github.com/digitalghost-dev/poke-cli/cmd/utils" "github.com/digitalghost-dev/poke-cli/flags" "github.com/digitalghost-dev/poke-cli/styling" "os" "runtime/debug" + "strings" ) var version = "(devel)" @@ -38,13 +40,9 @@ func currentVersion() { } } -func printWrapper(f func() string) func() { - return func() { - fmt.Println(f()) - } -} - func runCLI(args []string) int { + var output strings.Builder + mainFlagSet := flag.NewFlagSet("poke-cli", flag.ContinueOnError) // -l, --latest flag retrieves the latest Docker image and GitHub release versions available @@ -97,27 +95,34 @@ func runCLI(args []string) int { } commands := map[string]func(){ - "ability": printWrapper(ability.AbilityCommand), - "move": printWrapper(move.MoveCommand), - "natures": printWrapper(natures.NaturesCommand), - "pokemon": cmd.PokemonCommand, - "types": printWrapper(types.TypesCommand), + "ability": utils.HandleCommandOutput(ability.AbilityCommand), + "move": utils.HandleCommandOutput(move.MoveCommand), + "natures": utils.HandleCommandOutput(natures.NaturesCommand), + "pokemon": utils.HandleCommandOutput(pokemon.PokemonCommand), + "types": utils.HandleCommandOutput(types.TypesCommand), "search": search.SearchCommand, } - if len(os.Args) < 2 { + cmdArg := "" + if len(os.Args) >= 2 { + cmdArg = os.Args[1] + } + cmdFunc, exists := commands[cmdArg] + + switch { + case len(os.Args) < 2: mainFlagSet.Usage() return 1 - } else if *latestFlag || *shortLatestFlag { + case *latestFlag || *shortLatestFlag: flags.LatestFlag() return 0 - } else if *currentVersionFlag || *shortCurrentVersionFlag { + case *currentVersionFlag || *shortCurrentVersionFlag: currentVersion() return 0 - } else if cmdFunc, exists := commands[os.Args[1]]; exists { + case exists: cmdFunc() return 0 - } else { + default: command := os.Args[1] errMessage := styling.ErrorBorder.Render( styling.ErrorColor.Render("Error!"), @@ -131,7 +136,11 @@ func runCLI(args []string) int { fmt.Sprintf("\n\t%-15s %s", "types", "Get details about a typing"), fmt.Sprintf("\n\nAlso run %s for more info!", styling.StyleBold.Render("poke-cli -h")), ) - fmt.Printf("%s\n", errMessage) + output.WriteString(errMessage) + + // This would typically be returned in a function or passed to something else + fmt.Println(output.String()) + return 1 } } diff --git a/cli_test.go b/cli_test.go index 793641f..84b17c2 100644 --- a/cli_test.go +++ b/cli_test.go @@ -2,6 +2,9 @@ package main import ( "bytes" + "github.com/digitalghost-dev/poke-cli/cmd/utils" + "github.com/digitalghost-dev/poke-cli/styling" + "github.com/stretchr/testify/assert" "os" "regexp" "testing" @@ -93,119 +96,28 @@ func TestRunCLI(t *testing.T) { expectedCode int }{ { - name: "No Arguments", - args: []string{}, - expectedOutput: "╭──────────────────────────────────────────────────────────╮\n" + - "│Welcome! This tool displays data related to Pokémon! │\n" + - "│ │\n" + - "│ USAGE: │\n" + - "│ poke-cli [flag] │\n" + - "│ poke-cli [flag] │\n" + - "│ poke-cli [flag] │\n" + - "│ │\n" + - "│ FLAGS: │\n" + - "│ -h, --help Shows the help menu │\n" + - "│ -l, --latest Prints the latest version available │\n" + - "│ -v, --version Prints the current version │\n" + - "│ │\n" + - "│ COMMANDS: │\n" + - "│ ability Get details about an ability │\n" + - "│ move Get details about a move │\n" + - "│ natures Get details about all natures │\n" + - "│ pokemon Get details about a Pokémon │\n" + - "│ search Search for a resource │\n" + - "│ types Get details about a typing │\n" + - "│ │\n" + - "│ hint: when calling a resource with a space, use a hyphen │\n" + - "│ example: poke-cli ability strong-jaw │\n" + - "│ example: poke-cli pokemon flutter-mane │\n" + - "╰──────────────────────────────────────────────────────────╯", - expectedCode: 0, - }, - { - name: "Help Flag Short", - args: []string{"-h"}, - expectedOutput: "╭──────────────────────────────────────────────────────────╮\n" + - "│Welcome! This tool displays data related to Pokémon! │\n" + - "│ │\n" + - "│ USAGE: │\n" + - "│ poke-cli [flag] │\n" + - "│ poke-cli [flag] │\n" + - "│ poke-cli [flag] │\n" + - "│ │\n" + - "│ FLAGS: │\n" + - "│ -h, --help Shows the help menu │\n" + - "│ -l, --latest Prints the latest version available │\n" + - "│ -v, --version Prints the current version │\n" + - "│ │\n" + - "│ COMMANDS: │\n" + - "│ ability Get details about an ability │\n" + - "│ move Get details about a move │\n" + - "│ natures Get details about all natures │\n" + - "│ pokemon Get details about a Pokémon │\n" + - "│ search Search for a resource │\n" + - "│ types Get details about a typing │\n" + - "│ │\n" + - "│ hint: when calling a resource with a space, use a hyphen │\n" + - "│ example: poke-cli ability strong-jaw │\n" + - "│ example: poke-cli pokemon flutter-mane │\n" + - "╰──────────────────────────────────────────────────────────╯", - expectedCode: 0, - }, - { - name: "Help Flag Long", - args: []string{"--help"}, - expectedOutput: "╭──────────────────────────────────────────────────────────╮\n" + - "│Welcome! This tool displays data related to Pokémon! │\n" + - "│ │\n" + - "│ USAGE: │\n" + - "│ poke-cli [flag] │\n" + - "│ poke-cli [flag] │\n" + - "│ poke-cli [flag] │\n" + - "│ │\n" + - "│ FLAGS: │\n" + - "│ -h, --help Shows the help menu │\n" + - "│ -l, --latest Prints the latest version available │\n" + - "│ -v, --version Prints the current version │\n" + - "│ │\n" + - "│ COMMANDS: │\n" + - "│ ability Get details about an ability │\n" + - "│ move Get details about a move │\n" + - "│ natures Get details about all natures │\n" + - "│ pokemon Get details about a Pokémon │\n" + - "│ search Search for a resource │\n" + - "│ types Get details about a typing │\n" + - "│ │\n" + - "│ hint: when calling a resource with a space, use a hyphen │\n" + - "│ example: poke-cli ability strong-jaw │\n" + - "│ example: poke-cli pokemon flutter-mane │\n" + - "╰──────────────────────────────────────────────────────────╯", - - expectedCode: 0, - }, - { - name: "Invalid Command", - args: []string{"invalid"}, - expectedOutput: "Error!", - expectedCode: 1, + name: "Test CLI help flag", + args: []string{"--help"}, + expectedOutput: utils.LoadGolden(t, "cli_help.golden"), + expectedCode: 0, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - exit = func(code int) {} + originalArgs := os.Args + os.Args = append([]string{"poke-cli"}, tt.args...) + defer func() { os.Args = originalArgs }() + + var exitCode int output := captureOutput(func() { - code := runCLI(tt.args) - if code != tt.expectedCode { - t.Errorf("Expected exit code %d, got %d", tt.expectedCode, code) - } + exitCode = runCLI(tt.args) }) - output = stripANSI(output) + cleanOutput := styling.StripANSI(output) - if !bytes.Contains([]byte(output), []byte(tt.expectedOutput)) { - t.Errorf("Expected output to contain %q, got %q", tt.expectedOutput, output) - } + assert.Equal(t, tt.expectedOutput, cleanOutput, "Output should match expected") + assert.Equal(t, tt.expectedCode, exitCode, "Exit code should match expected") }) } } diff --git a/cmd/ability/ability.go b/cmd/ability/ability.go index af804e2..06c0c19 100644 --- a/cmd/ability/ability.go +++ b/cmd/ability/ability.go @@ -13,7 +13,7 @@ import ( "strings" ) -func AbilityCommand() string { +func AbilityCommand() (string, error) { var output strings.Builder flag.Usage = func() { @@ -38,12 +38,12 @@ func AbilityCommand() string { if len(os.Args) == 3 && (os.Args[2] == "-h" || os.Args[2] == "--help") { flag.Usage() - return output.String() + return output.String(), nil } if err := utils.ValidateAbilityArgs(args); err != nil { output.WriteString(err.Error()) - return output.String() + return output.String(), err } endpoint := strings.ToLower(args[1]) @@ -55,7 +55,7 @@ func AbilityCommand() string { if os.Getenv("GO_TESTING") != "1" { os.Exit(1) } - return output.String() + return output.String(), err } abilitiesStruct, abilityName, err := connections.AbilityApiCall(endpoint, abilityName, connections.APIURL) @@ -64,7 +64,7 @@ func AbilityCommand() string { fmt.Fprintln(os.Stderr, err) os.Exit(1) } - return err.Error() + return err.Error(), nil } // Extract English short_effect @@ -108,11 +108,9 @@ func AbilityCommand() string { if *pokemonFlag || *shortPokemonFlag { if err := flags.PokemonAbilitiesFlag(&output, endpoint, abilityName); err != nil { output.WriteString(fmt.Sprintf("error parsing flags: %v\n", err)) - if os.Getenv("GO_TESTING") != "1" { - os.Exit(1) - } + return "", fmt.Errorf("error parsing flags: %w", err) } } - return output.String() + return output.String(), nil } diff --git a/cmd/ability/ability_test.go b/cmd/ability/ability_test.go index 98761eb..5da9108 100644 --- a/cmd/ability/ability_test.go +++ b/cmd/ability/ability_test.go @@ -32,6 +32,11 @@ func TestAbilityCommand(t *testing.T) { args: []string{"ability", "--help"}, expectedOutput: utils.LoadGolden(t, "ability_help.golden"), }, + { + name: "Ability help flag", + args: []string{"ability", "-h"}, + expectedOutput: utils.LoadGolden(t, "ability_help.golden"), + }, { name: "Ability command: clear-body", args: []string{"ability", "clear-body"}, @@ -43,6 +48,11 @@ func TestAbilityCommand(t *testing.T) { expectedOutput: utils.LoadGolden(t, "ability_misspelled.golden"), wantError: true, }, + { + name: "Ability command: --pokemon flag", + args: []string{"ability", "anger-point", "--pokemon"}, + expectedOutput: utils.LoadGolden(t, "ability_flag_pokemon.golden"), + }, } for _, tt := range tests { @@ -51,7 +61,7 @@ func TestAbilityCommand(t *testing.T) { os.Args = append([]string{"poke-cli"}, tt.args...) defer func() { os.Args = originalArgs }() - output := AbilityCommand() + output, _ := AbilityCommand() cleanOutput := styling.StripANSI(output) assert.Equal(t, tt.expectedOutput, cleanOutput, "Output should match expected") diff --git a/cmd/move/move.go b/cmd/move/move.go index 945a963..1fbf17f 100644 --- a/cmd/move/move.go +++ b/cmd/move/move.go @@ -15,7 +15,7 @@ import ( "strings" ) -func MoveCommand() string { +func MoveCommand() (string, error) { var output strings.Builder flag.Usage = func() { @@ -32,12 +32,12 @@ func MoveCommand() string { if len(os.Args) == 3 && (os.Args[2] == "-h" || os.Args[2] == "--help") { flag.Usage() - return output.String() + return output.String(), nil } if err := utils.ValidateMoveArgs(os.Args); err != nil { output.WriteString(err.Error()) - return output.String() + return output.String(), err } args := flag.Args() @@ -49,7 +49,7 @@ func MoveCommand() string { moveInfoContainer(&output, moveStruct, moveName) moveEffectContainer(&output, moveStruct) - return output.String() + return output.String(), nil } func moveInfoContainer(output *strings.Builder, moveStruct structs.MoveJSONStruct, moveName string) { diff --git a/cmd/move/move_test.go b/cmd/move/move_test.go index 479ab65..23459eb 100644 --- a/cmd/move/move_test.go +++ b/cmd/move/move_test.go @@ -28,15 +28,20 @@ func TestMoveCommand(t *testing.T) { expectedError bool }{ { - name: "Select 'Shadow-Ball' as move", - args: []string{"move", "shadow-ball"}, - expectedOutput: utils.LoadGolden(t, "move.golden"), + name: "Move help flag", + args: []string{"move", "--help"}, + expectedOutput: utils.LoadGolden(t, "move_help.golden"), }, { name: "Move help flag", - args: []string{"move", "--help"}, + args: []string{"move", "-h"}, expectedOutput: utils.LoadGolden(t, "move_help.golden"), }, + { + name: "Select 'Shadow-Ball' as move", + args: []string{"move", "shadow-ball"}, + expectedOutput: utils.LoadGolden(t, "move.golden"), + }, } for _, tt := range tests { @@ -45,7 +50,7 @@ func TestMoveCommand(t *testing.T) { os.Args = append([]string{"poke-cli"}, tt.args...) defer func() { os.Args = originalArgs }() - output := MoveCommand() + output, _ := MoveCommand() cleanOutput := styling.StripANSI(output) assert.Equal(t, tt.expectedOutput, cleanOutput, "Output should match expected") diff --git a/cmd/natures/natures.go b/cmd/natures/natures.go index f62ad84..7ef7677 100644 --- a/cmd/natures/natures.go +++ b/cmd/natures/natures.go @@ -11,7 +11,7 @@ import ( "strings" ) -func NaturesCommand() string { +func NaturesCommand() (string, error) { var output strings.Builder // Define the usage function @@ -28,12 +28,12 @@ func NaturesCommand() string { if len(os.Args) == 3 && (os.Args[2] == "-h" || os.Args[2] == "--help") { flag.Usage() - return output.String() + return output.String(), nil } if err := utils.ValidateNaturesArgs(os.Args); err != nil { output.WriteString(err.Error()) - return output.String() + return output.String(), err } output.WriteString("Natures affect the growth of a Pokémon.\n" + @@ -63,5 +63,5 @@ func NaturesCommand() string { output.WriteString(t.Render() + "\n") - return output.String() + return output.String(), nil } diff --git a/cmd/natures/natures_test.go b/cmd/natures/natures_test.go index 9174410..c495e21 100644 --- a/cmd/natures/natures_test.go +++ b/cmd/natures/natures_test.go @@ -20,6 +20,11 @@ func TestNaturesCommand(t *testing.T) { args: []string{"natures", "--help"}, expectedOutput: utils.LoadGolden(t, "natures_help.golden"), }, + { + name: "Natures help flag", + args: []string{"natures", "-h"}, + expectedOutput: utils.LoadGolden(t, "natures_help.golden"), + }, { name: "Invalid extra argument", args: []string{"natures", "brave"}, @@ -39,7 +44,7 @@ func TestNaturesCommand(t *testing.T) { os.Args = append([]string{"poke-cli"}, tt.args...) defer func() { os.Args = originalArgs }() - output := NaturesCommand() + output, _ := NaturesCommand() cleanOutput := styling.StripANSI(output) assert.Equal(t, tt.expectedOutput, cleanOutput, "Output should match expected") diff --git a/cmd/pokemon.go b/cmd/pokemon/pokemon.go similarity index 66% rename from cmd/pokemon.go rename to cmd/pokemon/pokemon.go index cc964f4..7709060 100644 --- a/cmd/pokemon.go +++ b/cmd/pokemon/pokemon.go @@ -1,4 +1,4 @@ -package cmd +package pokemon import ( "flag" @@ -15,7 +15,9 @@ import ( ) // PokemonCommand processes the Pokémon command -func PokemonCommand() { +func PokemonCommand() (string, error) { + var output strings.Builder + hintMessage := styling.StyleItalic.Render("options: [sm, md, lg]") flag.Usage = func() { @@ -33,40 +35,24 @@ func PokemonCommand() { fmt.Sprintf("\n\t%-30s %s", "-t, --types", "Prints the Pokémon's typing."), fmt.Sprintf("\n\t%-30s %s", "-h, --help", "Prints the help menu."), ) - fmt.Println(helpMessage) + output.WriteString(helpMessage) } pokeFlags, abilitiesFlag, shortAbilitiesFlag, imageFlag, shortImageFlag, statsFlag, shortStatsFlag, typesFlag, shortTypesFlag := flags.SetupPokemonFlagSet() args := os.Args - // Pre-parse validation for empty image flag values - for _, arg := range args { - if strings.HasPrefix(arg, "-i=") && len(arg) == 3 { - fmt.Println(styling.ErrorBorder.Render(styling.ErrorColor.Render("Error!"), "\nThe image flag (-i or --image) requires a non-empty value.\nValid sizes are: lg, md, sm.")) - os.Exit(1) - } - if strings.HasPrefix(arg, "--image=") && len(arg) == 8 { - fmt.Println(styling.ErrorBorder.Render(styling.ErrorColor.Render("Error!"), "\nThe image flag (-i or --image) requires a non-empty value.\nValid sizes are: lg, md, sm.")) - os.Exit(1) - } - if strings.HasPrefix(arg, "-image=") && len(arg) == 7 { - fmt.Println(styling.ErrorBorder.Render(styling.ErrorColor.Render("Error!"), "\nThe image flag (-i or --image) requires a non-empty value.\nValid sizes are: lg, md, sm.")) - os.Exit(1) - } - } - flag.Parse() if len(os.Args) == 3 && (os.Args[2] == "-h" || os.Args[2] == "--help") { flag.Usage() - return + return output.String(), nil } err := utils.ValidatePokemonArgs(args) if err != nil { - fmt.Println(err.Error()) - os.Exit(1) + output.WriteString(err.Error()) // This is the styled error + return output.String(), err } endpoint := strings.ToLower(args[1]) @@ -101,10 +87,12 @@ func PokemonCommand() { inches = 0 } - fmt.Printf( + output.WriteString(fmt.Sprintf( "Your selected Pokémon: %s\n%s National Pokédex #: %d\n%s Weight: %.1fkg (%.1f lbs)\n%s Height: %.1fm (%d′%02d″)\n", - capitalizedString, styling.ColoredBullet, pokemonID, styling.ColoredBullet, weightKilograms, weightPounds, styling.ColoredBullet, heightFeet, feet, inches, - ) + capitalizedString, styling.ColoredBullet, pokemonID, + styling.ColoredBullet, weightKilograms, weightPounds, + styling.ColoredBullet, heightFeet, feet, inches, + )) if *imageFlag != "" || *shortImageFlag != "" { // Determine the size based on the provided flags @@ -114,30 +102,32 @@ func PokemonCommand() { } // Call the ImageFlag function with the specified size - if err := flags.ImageFlag(endpoint, pokemonName, size); err != nil { - fmt.Println(err) - os.Exit(1) + if err := flags.ImageFlag(&output, endpoint, pokemonName, size); err != nil { + output.WriteString(fmt.Sprintf("error parsing flags: %v\n", err)) + return "", fmt.Errorf("error parsing flags: %w", err) } } if *abilitiesFlag || *shortAbilitiesFlag { - if err := flags.AbilitiesFlag(endpoint, pokemonName); err != nil { - fmt.Printf("Error: %s\n", err) - os.Exit(1) + if err := flags.AbilitiesFlag(&output, endpoint, pokemonName); err != nil { + output.WriteString(fmt.Sprintf("error parsing flags: %v\n", err)) + return "", fmt.Errorf("error parsing flags: %w", err) } } if *typesFlag || *shortTypesFlag { - if err := flags.TypesFlag(endpoint, pokemonName); err != nil { - fmt.Printf("Error: %s\n", err) - os.Exit(1) + if err := flags.TypesFlag(&output, endpoint, pokemonName); err != nil { + output.WriteString(fmt.Sprintf("error parsing flags: %v\n", err)) + return "", fmt.Errorf("error parsing flags: %w", err) } } if *statsFlag || *shortStatsFlag { - if err := flags.StatsFlag(endpoint, pokemonName); err != nil { - fmt.Printf("Error: %s\n", err) - os.Exit(1) + if err := flags.StatsFlag(&output, endpoint, pokemonName); err != nil { + output.WriteString(fmt.Sprintf("error parsing flags: %v\n", err)) + return "", fmt.Errorf("error parsing flags: %w", err) } } + + return output.String(), nil } diff --git a/cmd/pokemon/pokemon_test.go b/cmd/pokemon/pokemon_test.go new file mode 100644 index 0000000..5222430 --- /dev/null +++ b/cmd/pokemon/pokemon_test.go @@ -0,0 +1,75 @@ +package pokemon + +import ( + "github.com/digitalghost-dev/poke-cli/cmd/utils" + "github.com/digitalghost-dev/poke-cli/styling" + "github.com/stretchr/testify/assert" + "os" + "testing" +) + +func TestPokemonCommand(t *testing.T) { + err := os.Setenv("GO_TESTING", "1") + if err != nil { + t.Fatalf("Failed to set GO_TESTING env var: %v", err) + } + + defer func() { + err := os.Unsetenv("GO_TESTING") + if err != nil { + t.Logf("Warning: failed to unset GO_TESTING: %v", err) + } + }() + + tests := []struct { + name string + args []string + expectedOutput string + wantError bool + }{ + { + name: "Pokemon help flag", + args: []string{"pokemon", "--help"}, + expectedOutput: utils.LoadGolden(t, "pokemon_help.golden"), + }, + { + name: "Pokemon abilities flag", + args: []string{"pokemon", "metagross", "--abilities"}, + expectedOutput: utils.LoadGolden(t, "pokemon_abilities.golden"), + }, + { + name: "Pokemon image flag", + args: []string{"pokemon", "skeledirge", "--image=md"}, + expectedOutput: utils.LoadGolden(t, "pokemon_image.golden"), + }, + { + name: "Pokemon invalid image flag", + args: []string{"pokemon", "tryanitar", "--image="}, + expectedOutput: utils.LoadGolden(t, "pokemon_invalid_image_flag.golden"), + wantError: true, + }, + { + name: "Pokemon stats flag", + args: []string{"pokemon", "toxicroak", "--stats"}, + expectedOutput: utils.LoadGolden(t, "pokemon_stats.golden"), + }, + { + name: "Pokemon typed flags", + args: []string{"pokemon", "armarouge", "--types"}, + expectedOutput: utils.LoadGolden(t, "pokemon_types.golden"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + originalArgs := os.Args + os.Args = append([]string{"poke-cli"}, tt.args...) + defer func() { os.Args = originalArgs }() + + output, _ := PokemonCommand() + cleanOutput := styling.StripANSI(output) + + assert.Equal(t, tt.expectedOutput, cleanOutput, "Output should match expected") + }) + } +} diff --git a/cmd/pokemon_test.go b/cmd/pokemon_test.go deleted file mode 100644 index 7d0089d..0000000 --- a/cmd/pokemon_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package cmd - -import ( - "bytes" - "fmt" - "github.com/digitalghost-dev/poke-cli/styling" - "os" - "strings" - "testing" -) - -func capturePokemonOutput(f func()) string { - // Create a pipe to capture standard output - r, w, _ := os.Pipe() - defer func(r *os.File) { - err := r.Close() - if err != nil { - fmt.Println(err) - } - }(r) - - // Redirect os.Stdout to the write end of the pipe - oldStdout := os.Stdout - os.Stdout = w - defer func() { os.Stdout = oldStdout }() - - // Run the function - f() - - // Close the write end of the pipe - err := w.Close() - if err != nil { - return "" - } - - // Read the captured output - var buf bytes.Buffer - _, _ = buf.ReadFrom(r) - return buf.String() -} - -func TestPokemonCommand(t *testing.T) { - tests := []struct { - name string - args []string - expectedOutput string - expectedError bool - }{ - { - name: "Valid abilities flags", - args: []string{"pokemon", "sandile", "--abilities"}, - expectedOutput: styling.StripANSI("Your selected Pokémon: Sandile\n• National Pokédex #: 551\n• Weight: 15.2kg (33.5 lbs)\n• Height: 2.3m (2′04″)\n─────────\nAbilities\nAbility 1: Intimidate\nAbility 2: Moxie\nHidden Ability: Anger Point"), - expectedError: false, - }, - { - name: "Stats flags", - args: []string{"pokemon", "palafin-zero", "--stats"}, - expectedOutput: styling.StripANSI("Your selected Pokémon: Palafin Zero\n• National Pokédex #: 964\n• Weight: 60.2kg (132.7 lbs)\n• Height: 4.3m (4′03″)\n──────────\nBase Stats\nHP ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 100\nAtk ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 70\nDef ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 72\nSp. Atk ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 53\nSp. Def ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 62\nSpeed ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 100\nTotal 457"), - expectedError: false, - }, - { - name: "Types flags", - args: []string{"pokemon", "armarouge", "--types"}, - expectedOutput: styling.StripANSI("Your selected Pokémon: Armarouge\n• National Pokédex #: 936\n• Weight: 85.0kg (187.4 lbs)\n• Height: 4.9m (4′11″)\n──────\nTyping\nType 1: Fire\nType 2: Psychic"), - expectedError: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - // Save original os.Args - originalArgs := os.Args - defer func() { os.Args = originalArgs }() - - // Set os.Args for the test - os.Args = append([]string{"poke-cli"}, tt.args...) - - // Capture the output - output := capturePokemonOutput(func() { - defer func() { - // Recover from os.Exit calls - if r := recover(); r != nil { - if !tt.expectedError { - t.Fatalf("Unexpected error: %v", r) - } - } - }() - PokemonCommand() - }) - - cleanOutput := styling.StripANSI(output) - - // Check output - if !strings.Contains(cleanOutput, tt.expectedOutput) { - t.Logf("DEBUG: Full captured output:\n%s", cleanOutput) - t.Errorf("Output mismatch.\nExpected to contain:\n%s\nGot:\n%s", tt.expectedOutput, cleanOutput) - } - }) - } -} diff --git a/cmd/types/types.go b/cmd/types/types.go index 7b0a543..2d7caef 100644 --- a/cmd/types/types.go +++ b/cmd/types/types.go @@ -12,7 +12,7 @@ import ( "strings" ) -func TypesCommand() string { +func TypesCommand() (string, error) { var output strings.Builder flag.Usage = func() { @@ -31,18 +31,18 @@ func TypesCommand() string { if len(os.Args) == 3 && (os.Args[2] == "-h" || os.Args[2] == "--help") { flag.Usage() - return output.String() + return output.String(), nil } if err := utils.ValidateTypesArgs(os.Args); err != nil { output.WriteString(err.Error()) - os.Exit(1) + return output.String(), err } endpoint := strings.ToLower(os.Args[1])[0:4] tableGeneration(endpoint) - return output.String() + return output.String(), nil } type model struct { diff --git a/cmd/types/types_test.go b/cmd/types/types_test.go index b910e07..928404b 100644 --- a/cmd/types/types_test.go +++ b/cmd/types/types_test.go @@ -20,6 +20,11 @@ func TestTypesCommand(t *testing.T) { args: []string{"types", "--help"}, expectedOutput: utils.LoadGolden(t, "types_help.golden"), }, + { + name: "Types help flag", + args: []string{"types", "-h"}, + expectedOutput: utils.LoadGolden(t, "types_help.golden"), + }, } for _, tt := range tests { @@ -28,7 +33,7 @@ func TestTypesCommand(t *testing.T) { os.Args = append([]string{"poke-cli"}, tt.args...) defer func() { os.Args = originalArgs }() - output := TypesCommand() + output, _ := TypesCommand() cleanOutput := styling.StripANSI(output) assert.Equal(t, tt.expectedOutput, cleanOutput, "Output should match expected") diff --git a/cmd/utils/golden.go b/cmd/utils/golden.go index 0ea6474..a6df62c 100644 --- a/cmd/utils/golden.go +++ b/cmd/utils/golden.go @@ -10,15 +10,31 @@ import ( func LoadGolden(t *testing.T, filename string) string { t.Helper() - basePath := filepath.Join("../..", "testdata") + // Get the current working directory (e.g., cmd/types/) + wd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get working directory: %v", err) + } + + projectRoot := wd + for { + if _, err := os.Stat(filepath.Join(projectRoot, "go.mod")); err == nil { + break + } + parent := filepath.Dir(projectRoot) + if parent == projectRoot { + t.Fatal("could not find project root (go.mod)") + } + projectRoot = parent + } + + testdataPath := filepath.Join(projectRoot, "testdata") - // gosec - joinedPath := filepath.Join(basePath, filename) + joinedPath := filepath.Join(testdataPath, filename) cleanPath := filepath.Clean(joinedPath) - // Ensure the cleaned path is still within basePath - basePathClean := filepath.Clean(basePath) - if !strings.HasPrefix(cleanPath, basePathClean+string(os.PathSeparator)) { + testdataPathClean := filepath.Clean(testdataPath) + if !strings.HasPrefix(cleanPath, testdataPathClean+string(os.PathSeparator)) { t.Fatalf("invalid filename: %q", filename) } diff --git a/cmd/utils/output.go b/cmd/utils/output.go new file mode 100644 index 0000000..2f74c9c --- /dev/null +++ b/cmd/utils/output.go @@ -0,0 +1,19 @@ +package utils + +import ( + "fmt" + "os" +) + +// HandleCommandOutput wraps a function that returns (string, error) into a no-arg function +// that prints the output to stdout or stderr depending on whether an error occurred. +func HandleCommandOutput(fn func() (string, error)) func() { + return func() { + output, err := fn() + if err != nil { + fmt.Fprintln(os.Stderr, output) + return + } + fmt.Println(output) + } +} diff --git a/cmd/utils/output_test.go b/cmd/utils/output_test.go new file mode 100644 index 0000000..5bbd3c8 --- /dev/null +++ b/cmd/utils/output_test.go @@ -0,0 +1,51 @@ +package utils + +import ( + "errors" + "io" + "os" + "testing" +) + +func captureOutput(target **os.File, fn func()) string { + // Create pipe + r, w, _ := os.Pipe() + orig := *target + *target = w + + // Run the function + fn() + + // Restore original and read output + err := w.Close() + if err != nil { + return "" + } + *target = orig + out, _ := io.ReadAll(r) + return string(out) +} + +func TestHandleCommandOutput_Success(t *testing.T) { + fn := func() (string, error) { + return "it worked", nil + } + + output := captureOutput(&os.Stdout, HandleCommandOutput(fn)) + + if output != "it worked\n" { + t.Errorf("expected 'it worked\\n', got %q", output) + } +} + +func TestHandleCommandOutput_Error(t *testing.T) { + fn := func() (string, error) { + return "something failed", errors.New("error") + } + + output := captureOutput(&os.Stderr, HandleCommandOutput(fn)) + + if output != "something failed\n" { + t.Errorf("expected 'something failed\\n', got %q", output) + } +} diff --git a/cmd/utils/validateargs.go b/cmd/utils/validateargs.go index 9ed535b..28d28f9 100644 --- a/cmd/utils/validateargs.go +++ b/cmd/utils/validateargs.go @@ -3,6 +3,7 @@ package utils import ( "fmt" "github.com/digitalghost-dev/poke-cli/styling" + "strings" ) // checkLength checks if the number of arguments is lower than the max value @@ -55,7 +56,7 @@ func ValidateNaturesArgs(args []string) error { if len(args) == 3 && args[2] != "-h" && args[2] != "--help" { errMsg := styling.ErrorColor.Render("Error!") + "\nThe only currently available options\nafter command are '-h' or '--help'" - return fmt.Errorf("%s %s", styling.ErrorBorder.Render(errMsg), "\n") + return fmt.Errorf("%s", styling.ErrorBorder.Render(errMsg)) } return nil @@ -78,6 +79,25 @@ func ValidatePokemonArgs(args []string) error { return err } + printImageFlagError := func() error { + msg := styling.ErrorBorder.Render( + styling.ErrorColor.Render("Error!") + + "\nThe image flag (-i or --image) requires a non-empty value.\nValid sizes are: lg, md, sm.", + ) + return fmt.Errorf("%s", msg) + } + + for _, arg := range args { + switch { + case strings.HasPrefix(arg, "-i=") && strings.TrimPrefix(arg, "-i=") == "": + return printImageFlagError() + case strings.HasPrefix(arg, "--image=") && strings.TrimPrefix(arg, "--image=") == "": + return printImageFlagError() + case strings.HasPrefix(arg, "-image=") && strings.TrimPrefix(arg, "-image=") == "": + return printImageFlagError() + } + } + // Validate each argument after the Pokémon's name if len(args) > 3 { for _, arg := range args[3:] { diff --git a/flags/abilityflagset.go b/flags/abilityflagset.go index c902295..338ff1f 100644 --- a/flags/abilityflagset.go +++ b/flags/abilityflagset.go @@ -47,12 +47,18 @@ func PokemonAbilitiesFlag(w io.Writer, endpoint string, abilityName string) erro const cols = 3 for i, name := range pokemonNames { entry := fmt.Sprintf("%2d. %-30s", i+1, name) - fmt.Fprint(w, entry) + _, err := fmt.Fprint(w, entry) + if err != nil { + return err + } if (i+1)%cols == 0 { - fmt.Fprintln(w) + _, err := fmt.Fprintln(w) + if err != nil { + return err + } } } - if _, err := fmt.Fprintln(w); err != nil { + if _, err := fmt.Fprint(w); err != nil { return err } diff --git a/flags/pokemonflagset.go b/flags/pokemonflagset.go index 0eac408..c933097 100644 --- a/flags/pokemonflagset.go +++ b/flags/pokemonflagset.go @@ -12,12 +12,15 @@ import ( "golang.org/x/text/cases" "golang.org/x/text/language" "image" + "io" "net/http" "os" "strings" ) -func header(header string) { +func header(header string) string { + var output strings.Builder + HeaderBold := lipgloss.NewStyle(). BorderStyle(lipgloss.NormalBorder()). BorderForeground(lipgloss.Color("#FFCC00")). @@ -25,7 +28,9 @@ func header(header string) { Bold(true). Render(header) - fmt.Println(HeaderBold) + output.WriteString(HeaderBold) + + return output.String() } func SetupPokemonFlagSet() (*flag.FlagSet, *bool, *bool, *string, *string, *bool, *bool, *bool, *bool) { @@ -61,10 +66,14 @@ func SetupPokemonFlagSet() (*flag.FlagSet, *bool, *bool, *string, *string, *bool return pokeFlags, abilitiesFlag, shortAbilitiesFlag, imageFlag, shortImageFlag, statsFlag, shortStatsFlag, typesFlag, shortTypesFlag } -func AbilitiesFlag(endpoint string, pokemonName string) error { +func AbilitiesFlag(w io.Writer, endpoint string, pokemonName string) error { pokemonStruct, _, _, _, _, _ := connections.PokemonApiCall(endpoint, pokemonName, connections.APIURL) - header("Abilities") + // Print the header from header func + _, err := fmt.Fprintln(w, header("Abilities")) + if err != nil { + return err + } // Anonymous function to format ability names formatAbilityName := func(name string) string { @@ -95,20 +104,30 @@ func AbilitiesFlag(endpoint string, pokemonName string) error { switch pokeAbility.Slot { case 1, 2: - fmt.Printf("Ability %d: %s\n", pokeAbility.Slot, formattedName) + _, err := fmt.Fprintf(w, "Ability %d: %s\n", pokeAbility.Slot, formattedName) + if err != nil { + return err + } default: - fmt.Printf("Hidden Ability: %s\n", formattedName) + _, err := fmt.Fprintf(w, "Hidden Ability: %s\n", formattedName) + if err != nil { + return err + } } } return nil } -func ImageFlag(endpoint string, pokemonName string, size string) error { +func ImageFlag(w io.Writer, endpoint string, pokemonName string, size string) error { baseURL := "https://pokeapi.co/api/v2/" pokemonStruct, _, _, _, _, _ := connections.PokemonApiCall(endpoint, pokemonName, baseURL) - header("Image") + // Print the header from header func + _, err := fmt.Fprintln(w, header("Image")) + if err != nil { + return err + } // Anonymous function to transform the image to a string // ToString generates an ASCII representation of the image with color @@ -171,18 +190,25 @@ func ImageFlag(endpoint string, pokemonName string, size string) error { } imgStr := ToString(dimensions[0], dimensions[1], img) - fmt.Println(imgStr) + _, err = fmt.Fprint(w, imgStr) + if err != nil { + return err + } return nil } -func StatsFlag(endpoint string, pokemonName string) error { +func StatsFlag(w io.Writer, endpoint string, pokemonName string) error { baseURL := "https://pokeapi.co/api/v2/" pokemonStruct, _, _, _, _, _ := connections.PokemonApiCall(endpoint, pokemonName, baseURL) - header("Base Stats") + // Print the header from header func + _, err := fmt.Fprintln(w, header("Base Stats")) + if err != nil { + return err + } - // Anonymous function to map stat values to categories + // Anonymous function to map stat values to specific categories getStatCategory := func(value int) string { switch { case value < 20: @@ -205,7 +231,10 @@ func StatsFlag(endpoint string, pokemonName string) error { scaledValue := (value * maxWidth) / maxValue bar := strings.Repeat("▇", scaledValue) coloredBar := style.Render(bar) - fmt.Printf("%-10s %s %d\n", label, coloredBar, value) + _, err := fmt.Fprintf(w, "%-10s %s %d\n", label, coloredBar, value) + if err != nil { + return + } } // Mapping from API stat names to custom display names @@ -227,7 +256,7 @@ func StatsFlag(endpoint string, pokemonName string) error { "highest": "#00C2B8", } - // Find the maxium stat value + // Find the maximum stat value maxValue := 0 for _, stat := range pokemonStruct.Stats { if stat.BaseStat > maxValue { @@ -257,12 +286,15 @@ func StatsFlag(endpoint string, pokemonName string) error { totalBaseStats += stat.BaseStat } - fmt.Printf("%-10s %d\n", "Total", totalBaseStats) + _, err = fmt.Fprintf(w, "%-10s %d\n", "Total", totalBaseStats) + if err != nil { + return err + } return nil } -func TypesFlag(endpoint string, pokemonName string) error { +func TypesFlag(w io.Writer, endpoint string, pokemonName string) error { baseURL := "https://pokeapi.co/api/v2/" pokemonStruct, _, _, _, _, _ := connections.PokemonApiCall(endpoint, pokemonName, baseURL) @@ -287,17 +319,27 @@ func TypesFlag(endpoint string, pokemonName string) error { "fairy": "#EE99EE", } - header("Typing") + // Print the header from header func + _, err := fmt.Fprintln(w, header("Typing")) + if err != nil { + return err + } for _, pokeType := range pokemonStruct.Types { colorHex, exists := colorMap[pokeType.Type.Name] if exists { color := lipgloss.Color(colorHex) style := lipgloss.NewStyle().Bold(true).Foreground(color) - styledName := style.Render(cases.Title(language.English).String(pokeType.Type.Name)) // Apply styling here - fmt.Printf("Type %d: %s\n", pokeType.Slot, styledName) // Interpolate styled text + styledName := style.Render(cases.Title(language.English).String(pokeType.Type.Name)) + _, err := fmt.Fprintf(w, "Type %d: %s\n", pokeType.Slot, styledName) + if err != nil { + return err + } } else { - fmt.Printf("Type %d: %s\n", pokeType.Slot, cases.Title(language.English).String(pokeType.Type.Name)) + _, err := fmt.Fprintf(w, "Type %d: %s\n", pokeType.Slot, cases.Title(language.English).String(pokeType.Type.Name)) + if err != nil { + return err + } } } diff --git a/flags/pokemonflagset_test.go b/flags/pokemonflagset_test.go index 2e91cc4..2115417 100644 --- a/flags/pokemonflagset_test.go +++ b/flags/pokemonflagset_test.go @@ -50,7 +50,7 @@ func TestAbilitiesFlag(t *testing.T) { os.Stdout = w // Call the function with a known Pokémon (e.g., bulbasaur) - err := AbilitiesFlag("pokemon", "bulbasaur") + err := AbilitiesFlag(&output, "pokemon", "bulbasaur") // Close and restore stdout if closeErr := w.Close(); closeErr != nil { @@ -86,7 +86,7 @@ func TestImageFlag(t *testing.T) { os.Stdout = w // Call the function with a known Pokémon (e.g., bulbasaur) - err := ImageFlag("pokemon", "bulbasaur", "sm") + err := ImageFlag(&output, "pokemon", "bulbasaur", "sm") // Close and restore stdout if closeErr := w.Close(); closeErr != nil { @@ -122,7 +122,8 @@ func TestImageFlagOptions(t *testing.T) { // Test valid options for _, option := range validOptions { t.Run("ValidOption_"+option, func(t *testing.T) { - err := ImageFlag("pokemon", "bulbasaur", option) + var buf bytes.Buffer + err := ImageFlag(&buf, "pokemon", "bulbasaur", option) assert.NoError(t, err, "ImageFlag should not return an error for valid option '%s'", option) }) } @@ -133,7 +134,8 @@ func TestImageFlagOptions(t *testing.T) { // Test invalid options for _, option := range invalidOptions { t.Run("InvalidOption_"+option, func(t *testing.T) { - err := ImageFlag("pokemon", "bulbasaur", option) + var buf bytes.Buffer + err := ImageFlag(&buf, "pokemon", "bulbasaur", option) assert.Error(t, err, "ImageFlag should return an error for invalid option '%s'", option) }) } @@ -147,7 +149,7 @@ func TestStatsFlag(t *testing.T) { os.Stdout = w // Call the StatsFlag function with a valid Pokémon - err := StatsFlag("pokemon", "bulbasaur") + err := StatsFlag(&output, "pokemon", "bulbasaur") // Close and restore stdout if closeErr := w.Close(); closeErr != nil { @@ -188,7 +190,7 @@ func TestTypesFlag(t *testing.T) { os.Stdout = w // Call the TypesFlag function with a valid Pokémon - err := TypesFlag("pokemon", "bulbasaur") + err := TypesFlag(&output, "pokemon", "bulbasaur") // Close and restore stdout if closeErr := w.Close(); closeErr != nil { diff --git a/testdata/ability_flag_pokemon.golden b/testdata/ability_flag_pokemon.golden new file mode 100644 index 0000000..46e7bf8 --- /dev/null +++ b/testdata/ability_flag_pokemon.golden @@ -0,0 +1,10 @@ +Anger Point +Effect: Raises Attack to the maximum of six stages upon receiving a critical hit. +Generation: IV + +Pokemon with Anger Point + + 1. Mankey 2. Primeape 3. Tauros + 4. Camerupt 5. Sandile 6. Krokorok + 7. Krookodile 8. Crabrawler 9. Crabominable +10. Tauros-Paldea-Combat-Breed 11. Tauros-Paldea-Blaze-Breed 12. Tauros-Paldea-Aqua-Breed diff --git a/testdata/cli_help.golden b/testdata/cli_help.golden new file mode 100644 index 0000000..c116ad4 --- /dev/null +++ b/testdata/cli_help.golden @@ -0,0 +1,25 @@ +╭──────────────────────────────────────────────────────────╮ +│Welcome! This tool displays data related to Pokémon! │ +│ │ +│ USAGE: │ +│ poke-cli [flag] │ +│ poke-cli [flag] │ +│ poke-cli [flag] │ +│ │ +│ FLAGS: │ +│ -h, --help Shows the help menu │ +│ -l, --latest Prints the latest version available │ +│ -v, --version Prints the current version │ +│ │ +│ COMMANDS: │ +│ ability Get details about an ability │ +│ move Get details about a move │ +│ natures Get details about all natures │ +│ pokemon Get details about a Pokémon │ +│ search Search for a resource │ +│ types Get details about a typing │ +│ │ +│ hint: when calling a resource with a space, use a hyphen │ +│ example: poke-cli ability strong-jaw │ +│ example: poke-cli pokemon flutter-mane │ +╰──────────────────────────────────────────────────────────╯ diff --git a/testdata/cli_incorrect_command.golden b/testdata/cli_incorrect_command.golden new file mode 100644 index 0000000..8603c98 --- /dev/null +++ b/testdata/cli_incorrect_command.golden @@ -0,0 +1,14 @@ +╭──────────────────────────────────────────────────╮ +│Error! │ +│ 'movesets' is not a valid command. │ +│ │ +│Commands: │ +│ ability Get details about an ability │ +│ move Get details about a move │ +│ natures Get details about all natures │ +│ pokemon Get details about a Pokémon │ +│ search Search for a resource │ +│ types Get details about a typing │ +│ │ +│Also run poke-cli -h for more info! │ +╰──────────────────────────────────────────────────╯ \ No newline at end of file diff --git a/testdata/natures_invalid_extra_arg.golden b/testdata/natures_invalid_extra_arg.golden index 3e1c105..de50ee1 100644 --- a/testdata/natures_invalid_extra_arg.golden +++ b/testdata/natures_invalid_extra_arg.golden @@ -2,4 +2,4 @@ │Error! │ │The only currently available options │ │after command are '-h' or '--help'│ -╰────────────────────────────────────────────╯ +╰────────────────────────────────────────────╯ \ No newline at end of file diff --git a/testdata/pokemon_abilities.golden b/testdata/pokemon_abilities.golden new file mode 100644 index 0000000..6db91e3 --- /dev/null +++ b/testdata/pokemon_abilities.golden @@ -0,0 +1,8 @@ +Your selected Pokémon: Metagross +• National Pokédex #: 376 +• Weight: 550.0kg (1212.5 lbs) +• Height: 5.2m (5′03″) +───────── +Abilities +Ability 1: Clear Body +Hidden Ability: Light Metal diff --git a/testdata/pokemon_help.golden b/testdata/pokemon_help.golden new file mode 100644 index 0000000..09a1550 --- /dev/null +++ b/testdata/pokemon_help.golden @@ -0,0 +1,15 @@ +╭────────────────────────────────────────────────────────────────────────────╮ +│Get details about a specific Pokémon. │ +│ │ +│ USAGE: │ +│ poke-cli pokemon [flag] │ +│ Use a hyphen when typing a name with a space. │ +│ │ +│ FLAGS: │ +│ -a, --abilities Prints the Pokémon's abilities. │ +│ -i=xx, --image=xx Prints out the Pokémon's default sprite. │ +│ options: [sm, md, lg] │ +│ -s, --stats Prints the Pokémon's base stats. │ +│ -t, --types Prints the Pokémon's typing. │ +│ -h, --help Prints the help menu. │ +╰────────────────────────────────────────────────────────────────────────────╯ \ No newline at end of file diff --git a/testdata/pokemon_image.golden b/testdata/pokemon_image.golden new file mode 100644 index 0000000..7c4cdde --- /dev/null +++ b/testdata/pokemon_image.golden @@ -0,0 +1,48 @@ +Your selected Pokémon: Skeledirge +• National Pokédex #: 911 +• Weight: 326.5kg (719.8 lbs) +• Height: 5.2m (5′03″) +───── +Image +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ +▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ diff --git a/testdata/pokemon_invalid_image_flag.golden b/testdata/pokemon_invalid_image_flag.golden new file mode 100644 index 0000000..bfc1940 --- /dev/null +++ b/testdata/pokemon_invalid_image_flag.golden @@ -0,0 +1,5 @@ +╭──────────────────────────────────────────────────────────╮ +│Error! │ +│The image flag (-i or --image) requires a non-empty value.│ +│Valid sizes are: lg, md, sm. │ +╰──────────────────────────────────────────────────────────╯ \ No newline at end of file diff --git a/testdata/pokemon_stats.golden b/testdata/pokemon_stats.golden new file mode 100644 index 0000000..5dda8f7 --- /dev/null +++ b/testdata/pokemon_stats.golden @@ -0,0 +1,13 @@ +Your selected Pokémon: Toxicroak +• National Pokédex #: 454 +• Weight: 44.4kg (97.9 lbs) +• Height: 4.3m (4′03″) +────────── +Base Stats +HP ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 83 +Atk ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 106 +Def ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 65 +Sp. Atk ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 86 +Sp. Def ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 65 +Speed ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 85 +Total 490 diff --git a/testdata/pokemon_types.golden b/testdata/pokemon_types.golden new file mode 100644 index 0000000..52306ce --- /dev/null +++ b/testdata/pokemon_types.golden @@ -0,0 +1,8 @@ +Your selected Pokémon: Armarouge +• National Pokédex #: 936 +• Weight: 85.0kg (187.4 lbs) +• Height: 4.9m (4′11″) +────── +Typing +Type 1: Fire +Type 2: Psychic