diff --git a/.gitattributes b/.gitattributes index 9addb50..96c3d3a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6,7 +6,6 @@ /tests export-ignore /.gitattributes export-ignore /.gitignore export-ignore -/buddy.yml export-ignore /.php-cs-fixer.php export-ignore /phpstan.neon export-ignore /phpunit.xml export-ignore diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 86be36d..de78a65 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: true matrix: - php: ["7.4", "8.0", "8.1", "8.2", "8.3", "8.4"] + php: ["8.1", "8.2", "8.3", "8.4"] name: php-${{ matrix.php }} @@ -21,6 +21,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} + extensions: ctype, gd - name: Validate composer.json and composer.lock run: composer validate --strict @@ -34,7 +35,7 @@ jobs: restore-keys: | ${{ matrix.php }}-php- - name: Install dependencies - run: composer update --no-interaction --prefer-dist --no-progress + run: composer update --no-interaction --prefer-dist --no-progress --ansi - name: Execute tests - run: vendor/bin/phpunit --bootstrap vendor/autoload.php tests + run: vendor/bin/phpunit --color=always diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 472277c..62b3029 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -3,7 +3,7 @@ return (new PhpCsFixer\Config()) ->setRules([ '@PSR12' => true, - '@PHP74Migration' => true, + '@PHP81Migration' => true, 'binary_operator_spaces' => ['operators' => ['=>' => 'single_space', '=' => 'single_space']], 'blank_line_before_statement' => ['statements' => ['return']], 'cast_spaces' => true, @@ -23,7 +23,7 @@ 'self_accessor' => true, 'single_quote' => true, 'return_type_declaration' => true, - 'trailing_comma_in_multiline' => true, + 'trailing_comma_in_multiline' => ['elements' => ['arguments', 'arrays', 'match', 'parameters']], 'trim_array_spaces' => true, 'void_return' => true, ]) diff --git a/composer.json b/composer.json index 9cf8d00..6af3934 100644 --- a/composer.json +++ b/composer.json @@ -18,17 +18,16 @@ } ], "require": { - "php": "^7.4 || ^8.0", - "ext-ctype": "*", - "ext-json": "*" + "php": "^8.1", + "ext-ctype": "*" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.48", - "imagine/imagine": "^1.3", - "johnkary/phpunit-speedtrap": "^4.0", - "phpbench/phpbench": "^1.2", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^9.6" + "ergebnis/phpunit-slow-test-detector": "^2.19", + "friendsofphp/php-cs-fixer": "^3.75", + "imagine/imagine": "^1.5", + "phpbench/phpbench": "^1.4", + "phpstan/phpstan": "^1.12", + "phpunit/phpunit": "^10.5 || ^11.5 || ^12.2" }, "suggest": { "imagine/imagine": "To generate board images." diff --git a/phpunit.xml b/phpunit.xml index f0b3a67..77c1802 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,22 +1,15 @@ - + ./src - + @@ -24,7 +17,7 @@ - - - + + + diff --git a/src/Chess.php b/src/Chess.php index 3364ac4..9a6b9a7 100644 --- a/src/Chess.php +++ b/src/Chess.php @@ -321,7 +321,7 @@ protected function recordMove(Move $move): int $this->castling, $this->epSquare, $this->halfMoves, - $this->moveNumber + $this->moveNumber, )); return $this->history->key(); diff --git a/src/Entry.php b/src/Entry.php index fbdfdcf..ec9ac4a 100644 --- a/src/Entry.php +++ b/src/Entry.php @@ -4,47 +4,24 @@ namespace PChess\Chess; -class Entry +class Entry implements \Stringable { - public Move $move; - - public ?string $position; - - /** @var array */ - public array $kings; - public string $turn; - /** @var array */ - public array $castling; - - public ?int $epSquare; - - public int $halfMoves; - - public int $moveNumber; - /** * @param array $kings * @param array $castling */ public function __construct( - Move $move, - ?string $position, - array $kings, - array $castling, - ?int $epSquare, - int $halfMoves, - int $moveNumber + public Move $move, + public ?string $position, + public array $kings, + public array $castling, + public ?int $epSquare, + public int $halfMoves, + public int $moveNumber, ) { - $this->move = $move; - $this->position = $position; - $this->kings = $kings; $this->turn = $move->turn; - $this->castling = $castling; - $this->epSquare = $epSquare; - $this->halfMoves = $halfMoves; - $this->moveNumber = $moveNumber; } public function __toString(): string diff --git a/src/History.php b/src/History.php index c80ed3a..9a4a0a3 100644 --- a/src/History.php +++ b/src/History.php @@ -6,13 +6,9 @@ final class History { - /** @var array */ - private array $entries; - - /** @param array|null $entries */ - public function __construct(?array $entries = null) + /** @param array $entries */ + public function __construct(private array $entries = []) { - $this->entries = $entries ?? []; } public function add(Entry $entry): void diff --git a/src/Move.php b/src/Move.php index 759d6c8..698559b 100644 --- a/src/Move.php +++ b/src/Move.php @@ -4,7 +4,7 @@ namespace PChess\Chess; -final class Move implements \JsonSerializable +final class Move implements \JsonSerializable, \Stringable { public const BITS = [ 'NORMAL' => 1, @@ -16,12 +16,6 @@ final class Move implements \JsonSerializable 'QSIDE_CASTLE' => 64, ]; - public string $turn; - - public int $flags; - - public Piece $piece; - public string $from; public string $to; @@ -30,23 +24,21 @@ final class Move implements \JsonSerializable public int $toSquare; - public ?string $captured; - - public ?string $promotion; - public ?string $san = null; - public function __construct(string $turn, int $flags, Piece $piece, int $from, int $to, ?string $captured = null, ?string $promotion = null) - { - $this->turn = $turn; - $this->flags = $flags; - $this->piece = $piece; + public function __construct( + public string $turn, + public int $flags, + public Piece $piece, + int $from, + int $to, + public ?string $captured = null, + public ?string $promotion = null, + ) { $this->fromSquare = $from; $this->toSquare = $to; $this->from = self::getSquare($from); $this->to = self::getSquare($to); - $this->captured = $captured; - $this->promotion = $promotion; } public function __toString(): string @@ -60,7 +52,7 @@ public static function buildMove( int $from, int $to, int $flags, - ?string $promotion = null + ?string $promotion = null, ): self { $captured = null; if ($board[$to] !== null) { @@ -82,7 +74,7 @@ public static function buildMove( $from, $to, $captured, - $promotion + $promotion, ); } diff --git a/src/Output/ImagineOutput.php b/src/Output/ImagineOutput.php index 9a7e14a..2cec7e4 100644 --- a/src/Output/ImagineOutput.php +++ b/src/Output/ImagineOutput.php @@ -35,7 +35,7 @@ public function __construct( int $size = 400, bool $coords = false, string $darkSquareColor = '#8ca2ad', - string $liteSquareColor = '#dee3e6' + string $liteSquareColor = '#dee3e6', ) { $this->imagine = $imagine; $this->spritesPath = $spritesPath; diff --git a/src/Output/Link.php b/src/Output/Link.php index af9dd14..348463b 100644 --- a/src/Output/Link.php +++ b/src/Output/Link.php @@ -10,14 +10,8 @@ */ final class Link { - private ?string $class; - - private ?string $url; - - public function __construct(?string $class, ?string $url) + public function __construct(public ?string $class, public ?string $url) { - $this->class = $class; - $this->url = $url; } public function getClass(): ?string diff --git a/src/Piece.php b/src/Piece.php index 866e0fa..afc2baa 100644 --- a/src/Piece.php +++ b/src/Piece.php @@ -4,7 +4,7 @@ namespace PChess\Chess; -final class Piece implements \JsonSerializable +final class Piece implements \JsonSerializable, \Stringable { public const SYMBOLS = 'pnbrqkPNBRQK'; @@ -43,10 +43,6 @@ final class Piece implements \JsonSerializable self::KING => 5, ]; - private string $type; - - private string $color; - /** @var array */ private static array $types = [ self::PAWN, @@ -80,7 +76,7 @@ final class Piece implements \JsonSerializable ], ]; - public function __construct(string $type, string $color) + public function __construct(private string $type, private string $color) { if (!\in_array($type, self::$types, true)) { throw new \InvalidArgumentException('Invalid piece type'); @@ -88,8 +84,6 @@ public function __construct(string $type, string $color) if (!\in_array($color, self::$colors, true)) { throw new \InvalidArgumentException('Invalid piece color'); } - $this->type = $type; - $this->color = $color; } public function __toString(): string diff --git a/tests/AttackTest.php b/tests/AttackTest.php index baacd77..819bd35 100644 --- a/tests/AttackTest.php +++ b/tests/AttackTest.php @@ -8,7 +8,7 @@ use PChess\Chess\Piece; use PHPUnit\Framework\TestCase; -class AttackTest extends TestCase +final class AttackTest extends TestCase { public function testAttackedPawn(): void { diff --git a/tests/ChessPublicator.php b/tests/ChessPublicator.php index cc8155b..96996e9 100644 --- a/tests/ChessPublicator.php +++ b/tests/ChessPublicator.php @@ -10,7 +10,7 @@ use PChess\Chess\Move; // a proxy for testing protected method -class ChessPublicator extends Chess +final class ChessPublicator extends Chess { public function getBoard(): Board { @@ -41,7 +41,7 @@ public static function buildMovePublic( int $from, int $to, int $flags, - ?string $promotion = null + ?string $promotion = null, ): Move { return Move::buildMove($turn, $board, $from, $to, $flags, $promotion); } diff --git a/tests/ConstructorTest.php b/tests/ConstructorTest.php index 05f5a33..a105d01 100644 --- a/tests/ConstructorTest.php +++ b/tests/ConstructorTest.php @@ -13,7 +13,7 @@ use PChess\Chess\Piece; use PHPUnit\Framework\TestCase; -class ConstructorTest extends TestCase +final class ConstructorTest extends TestCase { public function testDefaultPosition(): void { diff --git a/tests/FenTest.php b/tests/FenTest.php index 9558772..babc520 100644 --- a/tests/FenTest.php +++ b/tests/FenTest.php @@ -6,13 +6,12 @@ use PChess\Chess\Board; use PChess\Chess\Validation; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; final class FenTest extends TestCase { - /** - * @dataProvider provider - */ + #[DataProvider('provider')] public function testValidate(string $fen, int $code): void { self::assertEquals($code, Validation::validateFen($fen)); diff --git a/tests/GameTest.php b/tests/GameTest.php index 8108f54..f70a23a 100644 --- a/tests/GameTest.php +++ b/tests/GameTest.php @@ -7,7 +7,7 @@ use PChess\Chess\Chess; use PHPUnit\Framework\TestCase; -class GameTest extends TestCase +final class GameTest extends TestCase { /** * TODO re-check this test. diff --git a/tests/MiscTest.php b/tests/MiscTest.php index 0982c2c..23c3089 100644 --- a/tests/MiscTest.php +++ b/tests/MiscTest.php @@ -6,7 +6,7 @@ use PHPUnit\Framework\TestCase; -class MiscTest extends TestCase +final class MiscTest extends TestCase { public function testHistorySAN(): void { diff --git a/tests/MoveTest.php b/tests/MoveTest.php index dd04364..f24b1b8 100644 --- a/tests/MoveTest.php +++ b/tests/MoveTest.php @@ -8,6 +8,7 @@ use PChess\Chess\Chess; use PChess\Chess\Move; use PChess\Chess\Piece; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; class MoveTest extends TestCase @@ -24,7 +25,7 @@ public function testBuildMove(): void $chess->getBoard(), Board::SQUARES['a2'], Board::SQUARES['a4'], - Move::BITS['NORMAL'] + Move::BITS['NORMAL'], )); self::assertEquals(Piece::PAWN, $move->piece->getType()); @@ -65,7 +66,7 @@ public function testMakeMoveAndCheckHistory(): void $chess->getBoard(), Board::SQUARES['a2'], Board::SQUARES['a4'], - Move::BITS['NORMAL'] + Move::BITS['NORMAL'], )); $chess->makeMovePublic($move); @@ -87,7 +88,7 @@ public function testMakeMoveAndCheckHistory(): void Board::SQUARES['a7'], Board::SQUARES['a8'], Move::BITS['PROMOTION'], - Piece::QUEEN + Piece::QUEEN, )); $chess->makeMovePublic($move); self::assertSame($chess->fen(), 'Q7/8/8/8/8/8/8/K6k b - - 0 1'); @@ -109,7 +110,7 @@ public function testUndoMoveAndCheckHistory(): void Board::SQUARES['a7'], Board::SQUARES['a8'], Move::BITS['PROMOTION'], - Piece::QUEEN + Piece::QUEEN, )); $chess->makeMovePublic($move); $chess->undoMovePublic(); @@ -125,7 +126,7 @@ public function testUndoMoveAndCheckHistory(): void Board::SQUARES['d2'], Board::SQUARES['d4'], Move::BITS['BIG_PAWN'], - Piece::QUEEN + Piece::QUEEN, )); $chess->makeMovePublic($move); $chess->undoMovePublic(); @@ -142,7 +143,7 @@ public function testUndoMoveAndCheckHistory(): void Board::SQUARES['d4'], Board::SQUARES['e5'], Move::BITS['CAPTURE'], - Piece::QUEEN + Piece::QUEEN, )); $chess->makeMovePublic($move); $chess->undoMovePublic(); @@ -158,8 +159,8 @@ public function testUndoMoveAndCheckHistory(): void $chess->getBoard(), Board::SQUARES['h2'], Board::SQUARES['h4'], - Move::BITS['NORMAL']//, - //~ Chess::QUEEN + Move::BITS['NORMAL'], + //~ Piece::QUEEN, )); $chess->makeMovePublic($move); $fenTmp1 = $chess->fen(); @@ -169,7 +170,7 @@ public function testUndoMoveAndCheckHistory(): void Board::SQUARES['g4'], Board::SQUARES['h3'], Move::BITS['EP_CAPTURE'], - Piece::QUEEN + Piece::QUEEN, )); $chess->makeMovePublic($move); $chess->undoMovePublic(); @@ -188,8 +189,8 @@ public function testUndoMoveAndCheckHistory(): void $chess->getBoard(), Board::SQUARES['e1'], Board::SQUARES['g1'], - Move::BITS['KSIDE_CASTLE']//, - //~ Piece::QUEEN + Move::BITS['KSIDE_CASTLE'], + //~ Piece::QUEEN, )); $chess->makeMovePublic($move); self::assertSame($chess->fen(), 'r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq - 5 4'); @@ -206,8 +207,8 @@ public function testUndoMoveAndCheckHistory(): void $chess->getBoard(), Board::SQUARES['e8'], Board::SQUARES['c8'], - Move::BITS['QSIDE_CASTLE']//, - //~ Piece::QUEEN + Move::BITS['QSIDE_CASTLE'], + //~ Piece::QUEEN, )); $chess->makeMovePublic($move); self::assertSame($chess->fen(), '2kr1b1r/pppq1ppp/2np1n2/1B2p2b/4P3/3P1N1P/PPPB1PP1/RN1QR1K1 w - - 3 9'); @@ -233,7 +234,7 @@ public function testMoveToSAN(): void $chess->getBoard(), Board::SQUARES['e2'], Board::SQUARES['e4'], - Move::BITS['NORMAL'] + Move::BITS['NORMAL'], )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -248,7 +249,7 @@ public function testMoveToSAN(): void $chess->getBoard(), Board::SQUARES['g8'], Board::SQUARES['f6'], - Move::BITS['NORMAL'] + Move::BITS['NORMAL'], )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -262,7 +263,7 @@ public function testMoveToSAN(): void $chess->getBoard(), Board::SQUARES['e4'], Board::SQUARES['d5'], - Move::BITS['CAPTURE'] + Move::BITS['CAPTURE'], )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -276,7 +277,7 @@ public function testMoveToSAN(): void $chess->getBoard(), Board::SQUARES['d5'], Board::SQUARES['e6'], - Move::BITS['EP_CAPTURE'] + Move::BITS['EP_CAPTURE'], )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -290,7 +291,7 @@ public function testMoveToSAN(): void $chess->getBoard(), Board::SQUARES['f6'], Board::SQUARES['d5'], - Move::BITS['CAPTURE'] + Move::BITS['CAPTURE'], )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -305,7 +306,7 @@ public function testMoveToSAN(): void Board::SQUARES['d7'], Board::SQUARES['d8'], Move::BITS['PROMOTION'], - Piece::ROOK + Piece::ROOK, )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -319,7 +320,7 @@ public function testMoveToSAN(): void $chess->getBoard(), Board::SQUARES['d8'], Board::SQUARES['f8'], - Move::BITS['NORMAL'] + Move::BITS['NORMAL'], )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -333,7 +334,7 @@ public function testMoveToSAN(): void $chess->getBoard(), Board::SQUARES['b6'], Board::SQUARES['b8'], - Move::BITS['NORMAL'] + Move::BITS['NORMAL'], )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -347,7 +348,7 @@ public function testMoveToSAN(): void $chess->getBoard(), Board::SQUARES['c4'], Board::SQUARES['d6'], - Move::BITS['CAPTURE'] + Move::BITS['CAPTURE'], )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -361,7 +362,7 @@ public function testMoveToSAN(): void $chess->getBoard(), Board::SQUARES['d5'], Board::SQUARES['d4'], - Move::BITS['CAPTURE'] + Move::BITS['CAPTURE'], )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -375,7 +376,7 @@ public function testMoveToSAN(): void $chess->getBoard(), Board::SQUARES['e4'], Board::SQUARES['d6'], - Move::BITS['CAPTURE'] + Move::BITS['CAPTURE'], )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -389,7 +390,7 @@ public function testMoveToSAN(): void $chess->getBoard(), Board::SQUARES['c4'], Board::SQUARES['d6'], - Move::BITS['CAPTURE'] + Move::BITS['CAPTURE'], )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -403,7 +404,7 @@ public function testMoveToSAN(): void $chess->getBoard(), Board::SQUARES['c4'], Board::SQUARES['d6'], - Move::BITS['CAPTURE'] + Move::BITS['CAPTURE'], )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -417,7 +418,7 @@ public function testMoveToSAN(): void $chess->getBoard(), Board::SQUARES['g6'], Board::SQUARES['d6'], - Move::BITS['CAPTURE'] + Move::BITS['CAPTURE'], )); $chess->makeMovePublic($move); $undo = $chess->undo(); @@ -472,9 +473,7 @@ public function testArrayMove(): void self::assertSame($chess->fen(), 'r1bqk1nr/1ppp1ppp/p1n5/2b1p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq - 2 5'); } - /** - * @dataProvider gameProvider - */ + #[DataProvider('gameProvider')] public static function testSANMoveFromRealGame(string $match, string $finalFen): void { $chess = new ChessPublicator(); diff --git a/tests/PerftTest.php b/tests/PerftTest.php index 701dd51..e64bddf 100644 --- a/tests/PerftTest.php +++ b/tests/PerftTest.php @@ -4,14 +4,13 @@ namespace PChess\Chess\Test; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; // source: https://chessprogramming.wikispaces.com/Perft+Results -class PerftTest extends TestCase +final class PerftTest extends TestCase { - /** - * @dataProvider provider - */ + #[DataProvider('provider')] public static function testPerft(string $fen, int $expectedDeep1, int $expectedDeep2): void { $chess = new ChessPublicator($fen); diff --git a/tests/PiecePlacementTest.php b/tests/PiecePlacementTest.php index 0f8ad8a..4890019 100644 --- a/tests/PiecePlacementTest.php +++ b/tests/PiecePlacementTest.php @@ -8,7 +8,7 @@ use PChess\Chess\Piece; use PHPUnit\Framework\TestCase; -class PiecePlacementTest extends TestCase +final class PiecePlacementTest extends TestCase { public function testAll(): void { diff --git a/tests/PieceTest.php b/tests/PieceTest.php index bd037f0..e1e25fe 100644 --- a/tests/PieceTest.php +++ b/tests/PieceTest.php @@ -7,7 +7,7 @@ use PChess\Chess\Piece; use PHPUnit\Framework\TestCase; -class PieceTest extends TestCase +final class PieceTest extends TestCase { public function testPieceString(): void { @@ -18,7 +18,7 @@ public function testPieceString(): void public function testJson(): void { $piece = new Piece('p', 'w'); - self::assertEquals('"P"', \json_encode($piece)); + self::assertEquals('"P"', \json_encode($piece, JSON_THROW_ON_ERROR)); } public function testInvalidPieceType(): void