-
Notifications
You must be signed in to change notification settings - Fork 3
Add tests #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Add tests #7
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
311b7e6
Add a wrapper for the database to allow injecting an implementation w…
Nodjo 0010eb9
Add an example of the sftp.json file that doesn't contain credentials
Nodjo 25f7894
Optimize CI runs ressource usage
Nodjo 1951897
Add a Db implementation for mysqli.
Nodjo 5705181
Set up a database for testing on CI
Nodjo f7a04e0
Use the msqli db implementation in tests instead of mocking the db
Nodjo 08574b8
Inject a RandomProvider into Game
Nodjo 5d8de4f
Write a first test for the game, GameBeginnerTest.php
Nodjo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| { | ||
| "name": "BGA Studio", | ||
| "host": "1.studio.boardgamearena.com", | ||
| "protocol": "sftp", | ||
| "port": 2022, | ||
| "username": "${SFTP_USERNAME}", | ||
| "remotePath": "/diceforge", | ||
| "password": "${SFTP_PASSWORD}", | ||
| "uploadOnSave": true, | ||
| "ignore": [ | ||
| ".git", | ||
| ".prettierignore", | ||
| ".prettierrcold", | ||
| ".vscode", | ||
| ".gitattributes", | ||
| ".gitignore", | ||
| "docs", | ||
| "rebellion.todo", | ||
| "tests", | ||
| "vendor", | ||
| "phpunit.xml.dist", | ||
| "phpunit.xml", | ||
| "phpunit.result.cache", | ||
| "composer.json", | ||
| "composer.lock", | ||
| "phpunit.xml", | ||
| "phpstan.neon", | ||
| "phpstan-custom-rules.neon" | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| <?php | ||
|
|
||
| namespace Bga\Games\diceforge\Entities; | ||
|
|
||
| use Bga\Games\diceforge\Framework\Orm\Column; | ||
| use Bga\Games\diceforge\Framework\Orm\Entity; | ||
| use Bga\Games\diceforge\Framework\Orm\Id; | ||
|
|
||
| #[Entity('player')] | ||
| class Player | ||
| { | ||
| #[Id] | ||
| #[Column('player_id')] | ||
| public int $id = 0; | ||
|
|
||
| #[Column('player_score')] | ||
| public int $score = 0; | ||
|
|
||
| #[Column('player_name')] | ||
| public string $name; | ||
|
|
||
| #[Column('player_color')] | ||
| public string $color; | ||
|
|
||
| public function __construct(string $name, string $color) | ||
| { | ||
| $this->name = $name; | ||
| $this->color = $color; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the player entry as expected by setupNewGame()'s $players array. | ||
| */ | ||
| public function toSetupArray(): array | ||
| { | ||
| return [ | ||
| 'player_canal' => '', | ||
| 'player_name' => $this->name, | ||
| 'player_avatar' => '', | ||
| ]; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| <?php | ||
|
|
||
| namespace Bga\Games\diceforge\Framework\Db; | ||
|
|
||
| /** | ||
| * Thin wrapper over BGA's Table static database methods. | ||
| * | ||
| * Method names and signatures intentionally mirror Table's statics so that | ||
| * call sites read identically to the BGA docs and mocks are trivial to write. | ||
| * | ||
| * Why this exists: Table's methods are `final public static`, so they cannot | ||
| * be directly mocked or injected. This interface solves that without adding | ||
| * any translation layer. | ||
| */ | ||
| interface Db | ||
| { | ||
| public function DbQuery(string $sql): null|\mysqli_result|bool; | ||
|
|
||
| public function getUniqueValueFromDB(string $sql): mixed; | ||
|
|
||
| public function getCollectionFromDB(string $sql, bool $bSingleValue = false): array; | ||
|
|
||
| public function getObjectListFromDB(string $sql, bool $bUniqueValue = false): array; | ||
|
|
||
| public function getNonEmptyCollectionFromDB(string $sql): array; | ||
|
|
||
| public function getObjectFromDB(string $sql): array; | ||
|
|
||
| public function mysql_fetch_assoc(\mysqli_result $result): array|false|null; | ||
|
|
||
| public function escape(string $value): string; | ||
|
Nodjo marked this conversation as resolved.
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| <?php | ||
|
|
||
| namespace Bga\Games\diceforge\Framework\Db; | ||
|
|
||
| /** | ||
| * mysqli-backed implementation of Db for local testing. | ||
| * | ||
| * Connects to a real MariaDB/MySQL server so all SQL — including | ||
| * mysql_fetch_assoc — works exactly as it does on the BGA platform. | ||
| * | ||
| * Run tests/setup-test-db.sh (once, with sudo) before using this class. | ||
| * | ||
| * Default connection targets the test database created by that script: | ||
| * host=127.0.0.1 user=bga_test password=bga_test db=bga_test | ||
| */ | ||
| class MysqliDb implements Db | ||
| { | ||
| public function __construct(private readonly \mysqli $mysqli) | ||
| { | ||
| } | ||
|
|
||
| public static function createForTest( | ||
| string $host = '127.0.0.1', | ||
| string $user = 'bga_test', | ||
| string $password = 'bga_test', | ||
| string $database = 'bga_test', | ||
| int $port = 3306, | ||
| ): self { | ||
| $mysqli = new \mysqli($host, $user, $password, $database, $port); | ||
| if ($mysqli->connect_error) { | ||
| throw new \RuntimeException("MysqliDb: connection failed: " . $mysqli->connect_error); | ||
| } | ||
| $mysqli->set_charset('utf8'); | ||
| return new self($mysqli); | ||
| } | ||
|
|
||
| public function getMysqli(): \mysqli | ||
| { | ||
| return $this->mysqli; | ||
| } | ||
|
|
||
| // ------------------------------------------------------------------------- | ||
| // Interface implementation | ||
| // ------------------------------------------------------------------------- | ||
|
|
||
| public function DbQuery(string $sql): null|\mysqli_result|bool | ||
| { | ||
| $result = $this->mysqli->query($sql); | ||
| if ($result === false) { | ||
| throw new \BgaSystemException("DbQuery failed: " . $this->mysqli->error . " | SQL: $sql"); | ||
| } | ||
| return $result; | ||
| } | ||
|
|
||
| public function getUniqueValueFromDB(string $sql): mixed | ||
| { | ||
| $result = $this->DbQuery($sql); | ||
| if (!($result instanceof \mysqli_result)) { | ||
| return null; | ||
| } | ||
| $rows = $result->fetch_all(MYSQLI_NUM); | ||
| $result->free(); | ||
| if (count($rows) > 1) { | ||
| throw new \BgaSystemException("getUniqueValueFromDB: query returned more than 1 row"); | ||
| } | ||
| return $rows[0][0] ?? null; | ||
| } | ||
|
|
||
| public function getCollectionFromDB(string $sql, bool $bSingleValue = false): array | ||
| { | ||
| $result = $this->DbQuery($sql); | ||
| if (!($result instanceof \mysqli_result)) { | ||
| return []; | ||
| } | ||
| $rows = $result->fetch_all(MYSQLI_ASSOC); | ||
| $result->free(); | ||
| $collection = []; | ||
| foreach ($rows as $row) { | ||
| $values = array_values($row); | ||
| $key = $values[0]; | ||
| $collection[$key] = $bSingleValue ? ($values[1] ?? null) : $row; | ||
| } | ||
| return $collection; | ||
| } | ||
|
|
||
| public function getObjectListFromDB(string $sql, bool $bUniqueValue = false): array | ||
| { | ||
| $result = $this->DbQuery($sql); | ||
| if (!($result instanceof \mysqli_result)) { | ||
| return []; | ||
| } | ||
| $rows = $result->fetch_all(MYSQLI_ASSOC); | ||
| $result->free(); | ||
| if (!$bUniqueValue) { | ||
| return $rows; | ||
| } | ||
| return array_map(fn (array $row) => reset($row), $rows); | ||
| } | ||
|
|
||
| public function getNonEmptyCollectionFromDB(string $sql): array | ||
| { | ||
| $result = $this->getCollectionFromDB($sql); | ||
| if (empty($result)) { | ||
| throw new \BgaSystemException("getNonEmptyCollectionFromDB: empty collection"); | ||
| } | ||
| return $result; | ||
| } | ||
|
|
||
| public function getObjectFromDB(string $sql): array | ||
| { | ||
| $result = $this->DbQuery($sql); | ||
| if (!($result instanceof \mysqli_result)) { | ||
| return []; | ||
| } | ||
| $rows = $result->fetch_all(MYSQLI_ASSOC); | ||
| $result->free(); | ||
| if (count($rows) > 1) { | ||
| throw new \BgaSystemException("getObjectFromDB: query returned more than 1 row"); | ||
| } | ||
| return $rows[0] ?? []; | ||
| } | ||
|
|
||
| public function mysql_fetch_assoc(\mysqli_result $result): array|false|null | ||
| { | ||
| return $result->fetch_assoc(); | ||
| } | ||
|
|
||
| public function escape(string $value): string | ||
| { | ||
| return $this->mysqli->real_escape_string($value); | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.