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