From ab882a2f5c93ba0ed13fb980c6bc69557d2cc3b7 Mon Sep 17 00:00:00 2001 From: Michael Kramer Date: Sat, 11 Jul 2026 16:51:14 +0200 Subject: [PATCH 1/4] Sync docs changes --- exercises/practice/anagram/.meta/config.json | 2 +- exercises/practice/isogram/.meta/config.json | 2 +- exercises/practice/pangram/.meta/config.json | 2 +- exercises/practice/sublist/.meta/config.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/practice/anagram/.meta/config.json b/exercises/practice/anagram/.meta/config.json index 5b897575c..2e02d319a 100644 --- a/exercises/practice/anagram/.meta/config.json +++ b/exercises/practice/anagram/.meta/config.json @@ -19,7 +19,7 @@ ".meta/example.php" ] }, - "blurb": "Given a word and a list of possible anagrams, select the correct sublist.", + "blurb": "Find the words that use the same letters as another word.", "source": "Inspired by the Extreme Startup game", "source_url": "https://github.com/rchatley/extreme_startup" } diff --git a/exercises/practice/isogram/.meta/config.json b/exercises/practice/isogram/.meta/config.json index 3ba5553fe..32bee6bf2 100644 --- a/exercises/practice/isogram/.meta/config.json +++ b/exercises/practice/isogram/.meta/config.json @@ -20,7 +20,7 @@ ".meta/example.php" ] }, - "blurb": "Determine if a word or phrase is an isogram.", + "blurb": "Determine whether a phrase is an isogram, a word with no repeated letters.", "source": "Wikipedia", "source_url": "https://en.wikipedia.org/wiki/Isogram" } diff --git a/exercises/practice/pangram/.meta/config.json b/exercises/practice/pangram/.meta/config.json index e8719e82b..ecd69df67 100644 --- a/exercises/practice/pangram/.meta/config.json +++ b/exercises/practice/pangram/.meta/config.json @@ -20,7 +20,7 @@ ".meta/example.php" ] }, - "blurb": "Determine if a sentence is a pangram.", + "blurb": "Determine whether a phrase uses every letter in the Latin alphabet.", "source": "Wikipedia", "source_url": "https://en.wikipedia.org/wiki/Pangram" } diff --git a/exercises/practice/sublist/.meta/config.json b/exercises/practice/sublist/.meta/config.json index b4508ccf2..f478a3bf2 100644 --- a/exercises/practice/sublist/.meta/config.json +++ b/exercises/practice/sublist/.meta/config.json @@ -13,5 +13,5 @@ ".meta/example.php" ] }, - "blurb": "Write a function to determine if a list is a sublist of another list." + "blurb": "Determine if a list is a sublist of another list." } From 2dbb490617e4ab3a490bbf40aaeba7effd7903d7 Mon Sep 17 00:00:00 2001 From: Michael Kramer Date: Sat, 11 Jul 2026 17:08:07 +0200 Subject: [PATCH 2/4] New test and reordered tests for bob --- exercises/practice/bob/.meta/tests.toml | 89 +++++----- exercises/practice/bob/BobTest.php | 220 +++++++++++++----------- 2 files changed, 162 insertions(+), 147 deletions(-) diff --git a/exercises/practice/bob/.meta/tests.toml b/exercises/practice/bob/.meta/tests.toml index 5299e2895..c6a464960 100644 --- a/exercises/practice/bob/.meta/tests.toml +++ b/exercises/practice/bob/.meta/tests.toml @@ -9,17 +9,20 @@ # As user-added comments (using the # character) will be removed when this file # is regenerated, comments can be added via a `comment` key. -[e162fead-606f-437a-a166-d051915cea8e] -description = "stating something" +[8a2e771d-d6f1-4e3f-b6c6-b41495556e37] +description = "asking a question" [73a966dc-8017-47d6-bb32-cf07d1a5fcd9] description = "shouting" -[d6c98afd-df35-4806-b55e-2c457c3ab748] -description = "shouting gibberish" +[a5193c61-4a92-4f68-93e2-f554eb385ec6] +description = "forceful question" -[8a2e771d-d6f1-4e3f-b6c6-b41495556e37] -description = "asking a question" +[bc39f7c6-f543-41be-9a43-fd1c2f753fc0] +description = "silence" + +[e162fead-606f-437a-a166-d051915cea8e] +description = "stating something" [81080c62-4e4d-4066-b30a-48d8d76920d9] description = "asking a numeric question" @@ -27,23 +30,34 @@ description = "asking a numeric question" [2a02716d-685b-4e2e-a804-2adaf281c01e] description = "asking gibberish" -[c02f9179-ab16-4aa7-a8dc-940145c385f7] -description = "talking forcefully" +[bb0011c5-cd52-4a5b-8bfb-a87b6283b0e2] +description = "question with no letters" -[153c0e25-9bb5-4ec5-966e-598463658bcd] -description = "using acronyms in regular speech" +[9bfc677d-ea3a-45f2-be44-35bc8fa3753e] +description = "non-letters with question" -[a5193c61-4a92-4f68-93e2-f554eb385ec6] -description = "forceful question" +[8608c508-f7de-4b17-985b-811878b3cf45] +description = "prattling on" -[a20e0c54-2224-4dde-8b10-bd2cdd4f61bc] -description = "shouting numbers" +[05b304d6-f83b-46e7-81e0-4cd3ca647900] +description = "ending with whitespace" -[f7bc4b92-bdff-421e-a238-ae97f230ccac] -description = "no letters" +[66953780-165b-4e7e-8ce3-4bcb80b6385a] +description = "multiple line question" +include = false -[bb0011c5-cd52-4a5b-8bfb-a87b6283b0e2] -description = "question with no letters" +[2c7278ac-f955-4eb4-bf8f-e33eb4116a15] +description = "multiple line question" +reimplements = "66953780-165b-4e7e-8ce3-4bcb80b6385a" + +[d6c98afd-df35-4806-b55e-2c457c3ab748] +description = "shouting gibberish" + +[3c954328-86fb-4c71-8961-e18d6a5e2517] +description = "shouting a statement containing a question mark" + +[a20e0c54-2224-4dde-8b10-bd2cdd4f61bc] +description = "shouting numbers" [496143c8-1c31-4c01-8a08-88427af85c66] description = "shouting with special characters" @@ -51,40 +65,29 @@ description = "shouting with special characters" [e6793c1c-43bd-4b8d-bc11-499aea73925f] description = "shouting with no exclamation mark" -[aa8097cc-c548-4951-8856-14a404dd236a] -description = "statement containing question mark" - -[9bfc677d-ea3a-45f2-be44-35bc8fa3753e] -description = "non-letters with question" - -[8608c508-f7de-4b17-985b-811878b3cf45] -description = "prattling on" - -[bc39f7c6-f543-41be-9a43-fd1c2f753fc0] -description = "silence" - [d6c47565-372b-4b09-b1dd-c40552b8378b] description = "prolonged silence" [4428f28d-4100-4d85-a902-e5a78cb0ecd3] description = "alternate silence" -[66953780-165b-4e7e-8ce3-4bcb80b6385a] -description = "multiple line question" -include = false +[72bd5ad3-9b2f-4931-a988-dce1f5771de2] +description = "other whitespace" -[5371ef75-d9ea-4103-bcfa-2da973ddec1b] -description = "starting with whitespace" +[c02f9179-ab16-4aa7-a8dc-940145c385f7] +description = "talking forcefully" -[05b304d6-f83b-46e7-81e0-4cd3ca647900] -description = "ending with whitespace" +[153c0e25-9bb5-4ec5-966e-598463658bcd] +description = "using acronyms in regular speech" -[72bd5ad3-9b2f-4931-a988-dce1f5771de2] -description = "other whitespace" +[f7bc4b92-bdff-421e-a238-ae97f230ccac] +description = "no letters" + +[aa8097cc-c548-4951-8856-14a404dd236a] +description = "statement containing question mark" + +[5371ef75-d9ea-4103-bcfa-2da973ddec1b] +description = "starting with whitespace" [12983553-8601-46a8-92fa-fcaa3bc4a2a0] description = "non-question ending with whitespace" - -[2c7278ac-f955-4eb4-bf8f-e33eb4116a15] -description = "multiple line question" -reimplements = "66953780-165b-4e7e-8ce3-4bcb80b6385a" diff --git a/exercises/practice/bob/BobTest.php b/exercises/practice/bob/BobTest.php index 3543d4a2a..15fcb688a 100644 --- a/exercises/practice/bob/BobTest.php +++ b/exercises/practice/bob/BobTest.php @@ -13,13 +13,13 @@ public static function setUpBeforeClass(): void } /** - * uuid: e162fead-606f-437a-a166-d051915cea8e + * uuid: 8a2e771d-d6f1-4e3f-b6c6-b41495556e37 */ - #[TestDox('Stating something')] - public function testStatingSomething(): void + #[TestDox('Asking a question')] + public function testAskingAQuestion(): void { - $input = "Tom-ay-to, tom-aaaah-to."; - $expected = "Whatever."; + $input = "Does this cryogenic chamber make me look fat?"; + $expected = "Sure."; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } @@ -37,25 +37,37 @@ public function testShouting(): void } /** - * uuid: d6c98afd-df35-4806-b55e-2c457c3ab748 + * uuid: a5193c61-4a92-4f68-93e2-f554eb385ec6 */ - #[TestDox('Shouting gibberish')] - public function testShoutingGibberish(): void + #[TestDox('Forceful question')] + public function testForcefulQuestion(): void { - $input = "FCECDFCAAB"; - $expected = "Whoa, chill out!"; + $input = "WHAT'S GOING ON?"; + $expected = "Calm down, I know what I'm doing!"; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: 8a2e771d-d6f1-4e3f-b6c6-b41495556e37 + * uuid: bc39f7c6-f543-41be-9a43-fd1c2f753fc0 */ - #[TestDox('Asking a question')] - public function testAskingAQuestion(): void + #[TestDox('Silence')] + public function testSilence(): void { - $input = "Does this cryogenic chamber make me look fat?"; - $expected = "Sure."; + $input = ""; + $expected = "Fine. Be that way!"; + $subject = new Bob(); + $this->assertEquals($expected, $subject->respondTo($input)); + } + + /** + * uuid: e162fead-606f-437a-a166-d051915cea8e + */ + #[TestDox('Stating something')] + public function testStatingSomething(): void + { + $input = "Tom-ay-to, tom-aaaah-to."; + $expected = "Whatever."; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } @@ -85,229 +97,229 @@ public function testAskingGibberish(): void } /** - * uuid: c02f9179-ab16-4aa7-a8dc-940145c385f7 + * uuid: bb0011c5-cd52-4a5b-8bfb-a87b6283b0e2 */ - #[TestDox('Talking forcefully')] - public function testTalkingForcefully(): void + #[TestDox('Question with no letters')] + public function testQuestionWithOnlyNumbers(): void { - $input = "Hi there!"; - $expected = "Whatever."; + $input = "4?"; + $expected = "Sure."; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: 153c0e25-9bb5-4ec5-966e-598463658bcd + * uuid: 9bfc677d-ea3a-45f2-be44-35bc8fa3753e */ - #[TestDox('Using acronyms in regular speech')] - public function testUsingAcronymsInRegularSpeech(): void + #[TestDox('Non-letters with question')] + public function testNonLettersWithQuestion(): void { - $input = "It's OK if you don't want to go work for NASA."; - $expected = "Whatever."; + $input = ":) ?"; + $expected = "Sure."; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: a5193c61-4a92-4f68-93e2-f554eb385ec6 + * uuid: 8608c508-f7de-4b17-985b-811878b3cf45 */ - #[TestDox('Forceful question')] - public function testForcefulQuestion(): void + #[TestDox('Prattling on')] + public function testPrattlingOn(): void { - $input = "WHAT'S GOING ON?"; - $expected = "Calm down, I know what I'm doing!"; + $input = "Wait! Hang on. Are you going to be OK?"; + $expected = "Sure."; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: a20e0c54-2224-4dde-8b10-bd2cdd4f61bc + * uuid: 05b304d6-f83b-46e7-81e0-4cd3ca647900 */ - #[TestDox('Shouting numbers')] - public function testShoutingNumbers(): void + #[TestDox('Ending with whitespace')] + public function testEndingWithWhitespace(): void { - $input = "1, 2, 3 GO!"; - $expected = "Whoa, chill out!"; + $input = "Okay if like my spacebar quite a bit? "; + $expected = "Sure."; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: f7bc4b92-bdff-421e-a238-ae97f230ccac + * uuid: 2c7278ac-f955-4eb4-bf8f-e33eb4116a15 */ - #[TestDox('No letters')] - public function testOnlyNumbers(): void + #[TestDox('Multiple line question')] + public function testMultipleLineQuestion(): void { - $input = "1, 2, 3"; - $expected = "Whatever."; + $input = "\nDoes this cryogenic chamber make\n me look fat?"; + $expected = "Sure."; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: bb0011c5-cd52-4a5b-8bfb-a87b6283b0e2 + * uuid: d6c98afd-df35-4806-b55e-2c457c3ab748 */ - #[TestDox('Question with no letters')] - public function testQuestionWithOnlyNumbers(): void + #[TestDox('Shouting gibberish')] + public function testShoutingGibberish(): void { - $input = "4?"; - $expected = "Sure."; + $input = "FCECDFCAAB"; + $expected = "Whoa, chill out!"; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: 496143c8-1c31-4c01-8a08-88427af85c66 + * uuid: 3c954328-86fb-4c71-8961-e18d6a5e2517 */ - #[TestDox('Shouting with special characters')] - public function testShoutingWithSpecialCharacters(): void + #[TestDox('Shouting a statement containing a question mark')] + public function testShoutingAStatementContainingAQuestionMark(): void { - $input = "ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!"; + $input = "DO LIONS EAT PEOPLE? AHHHHH."; $expected = "Whoa, chill out!"; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: e6793c1c-43bd-4b8d-bc11-499aea73925f + * uuid: a20e0c54-2224-4dde-8b10-bd2cdd4f61bc */ - #[TestDox('Shouting with no exclamation mark')] - public function testShoutingWithNoExclamationMark(): void + #[TestDox('Shouting numbers')] + public function testShoutingNumbers(): void { - $input = "I HATE THE DENTIST"; + $input = "1, 2, 3 GO!"; $expected = "Whoa, chill out!"; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: aa8097cc-c548-4951-8856-14a404dd236a + * uuid: 496143c8-1c31-4c01-8a08-88427af85c66 */ - #[TestDox('Statement containing question mark')] - public function testStatementContainingQuestionMark(): void + #[TestDox('Shouting with special characters')] + public function testShoutingWithSpecialCharacters(): void { - $input = "Ending with ? means a question."; - $expected = "Whatever."; + $input = "ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!"; + $expected = "Whoa, chill out!"; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: 9bfc677d-ea3a-45f2-be44-35bc8fa3753e + * uuid: e6793c1c-43bd-4b8d-bc11-499aea73925f */ - #[TestDox('Non-letters with question')] - public function testNonLettersWithQuestion(): void + #[TestDox('Shouting with no exclamation mark')] + public function testShoutingWithNoExclamationMark(): void { - $input = ":) ?"; - $expected = "Sure."; + $input = "I HATE THE DENTIST"; + $expected = "Whoa, chill out!"; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: 8608c508-f7de-4b17-985b-811878b3cf45 + * uuid: d6c47565-372b-4b09-b1dd-c40552b8378b */ - #[TestDox('Prattling on')] - public function testPrattlingOn(): void + #[TestDox('Prolonged silence')] + public function testProlongedSilence(): void { - $input = "Wait! Hang on. Are you going to be OK?"; - $expected = "Sure."; + $input = " "; + $expected = "Fine. Be that way!"; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: bc39f7c6-f543-41be-9a43-fd1c2f753fc0 + * uuid: 4428f28d-4100-4d85-a902-e5a78cb0ecd3 */ - #[TestDox('Silence')] - public function testSilence(): void + #[TestDox('Alternate silence')] + public function testAlternateSilence(): void { - $input = ""; + $input = "\t\t\t\t\t\t\t\t\t\t"; $expected = "Fine. Be that way!"; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: d6c47565-372b-4b09-b1dd-c40552b8378b + * uuid: 72bd5ad3-9b2f-4931-a988-dce1f5771de2 */ - #[TestDox('Prolonged silence')] - public function testProlongedSilence(): void + #[TestDox('Other whitespace')] + public function testOtherWhitespace() { - $input = " "; + $input = "\n\r \t"; $expected = "Fine. Be that way!"; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: 4428f28d-4100-4d85-a902-e5a78cb0ecd3 + * uuid: c02f9179-ab16-4aa7-a8dc-940145c385f7 */ - #[TestDox('Alternate silence')] - public function testAlternateSilence(): void + #[TestDox('Talking forcefully')] + public function testTalkingForcefully(): void { - $input = "\t\t\t\t\t\t\t\t\t\t"; - $expected = "Fine. Be that way!"; + $input = "Hi there!"; + $expected = "Whatever."; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: 5371ef75-d9ea-4103-bcfa-2da973ddec1b + * uuid: 153c0e25-9bb5-4ec5-966e-598463658bcd */ - #[TestDox('Starting with whitespace')] - public function testStartingWithWhitespace(): void + #[TestDox('Using acronyms in regular speech')] + public function testUsingAcronymsInRegularSpeech(): void { - $input = " hmmmmmmm..."; + $input = "It's OK if you don't want to go work for NASA."; $expected = "Whatever."; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: 05b304d6-f83b-46e7-81e0-4cd3ca647900 + * uuid: f7bc4b92-bdff-421e-a238-ae97f230ccac */ - #[TestDox('Ending with whitespace')] - public function testEndingWithWhitespace(): void + #[TestDox('No letters')] + public function testOnlyNumbers(): void { - $input = "Okay if like my spacebar quite a bit? "; - $expected = "Sure."; + $input = "1, 2, 3"; + $expected = "Whatever."; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: 72bd5ad3-9b2f-4931-a988-dce1f5771de2 + * uuid: aa8097cc-c548-4951-8856-14a404dd236a */ - #[TestDox('Other whitespace')] - public function testOtherWhitespace() + #[TestDox('Statement containing question mark')] + public function testStatementContainingQuestionMark(): void { - $input = "\n\r \t"; - $expected = "Fine. Be that way!"; + $input = "Ending with ? means a question."; + $expected = "Whatever."; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: 12983553-8601-46a8-92fa-fcaa3bc4a2a0 + * uuid: 5371ef75-d9ea-4103-bcfa-2da973ddec1b */ - #[TestDox('Non-question ending with whitespace')] - public function testNonQuestionEndingWithWhitespace(): void + #[TestDox('Starting with whitespace')] + public function testStartingWithWhitespace(): void { - $input = "This is a statement ending with whitespace "; + $input = " hmmmmmmm..."; $expected = "Whatever."; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } /** - * uuid: 2c7278ac-f955-4eb4-bf8f-e33eb4116a15 + * uuid: 12983553-8601-46a8-92fa-fcaa3bc4a2a0 */ - #[TestDox('Multiple line question')] - public function testMultipleLineQuestion(): void + #[TestDox('Non-question ending with whitespace')] + public function testNonQuestionEndingWithWhitespace(): void { - $input = "\nDoes this cryogenic chamber make\n me look fat?"; - $expected = "Sure."; + $input = "This is a statement ending with whitespace "; + $expected = "Whatever."; $subject = new Bob(); $this->assertEquals($expected, $subject->respondTo($input)); } From 0d200a6e26a111ef74805270c6bb4a35ddb686cc Mon Sep 17 00:00:00 2001 From: Michael Kramer Date: Sat, 11 Jul 2026 17:58:27 +0200 Subject: [PATCH 3/4] Resync state-of-tic-tac-toe - Inline subject instantiation - Add TestDox attributes - New tests with adjusted example.php --- .../state-of-tic-tac-toe/.meta/example.php | 6 +- .../state-of-tic-tac-toe/.meta/tests.toml | 6 + .../StateOfTicTacToeTest.php | 170 +++++++++++++----- 3 files changed, 138 insertions(+), 44 deletions(-) diff --git a/exercises/practice/state-of-tic-tac-toe/.meta/example.php b/exercises/practice/state-of-tic-tac-toe/.meta/example.php index 7f6f41225..2995ee810 100644 --- a/exercises/practice/state-of-tic-tac-toe/.meta/example.php +++ b/exercises/practice/state-of-tic-tac-toe/.meta/example.php @@ -27,7 +27,11 @@ public function gameState(array $board): State $xWon = $this->hasWon($board, 'X'); $oWon = $this->hasWon($board, 'O'); - if ($xWon && $oWon) { + if ( + ($xCount === $oCount && $xWon) + || ($xCount > $oCount && $oWon) + || ($xWon && $oWon) + ) { throw new \RuntimeException("Impossible board: game should have ended after the game was won"); } diff --git a/exercises/practice/state-of-tic-tac-toe/.meta/tests.toml b/exercises/practice/state-of-tic-tac-toe/.meta/tests.toml index 8fc25e211..5f574b2a1 100644 --- a/exercises/practice/state-of-tic-tac-toe/.meta/tests.toml +++ b/exercises/practice/state-of-tic-tac-toe/.meta/tests.toml @@ -99,3 +99,9 @@ reimplements = "b1dc8b13-46c4-47db-a96d-aa90eedc4e8d" [4801cda2-f5b7-4c36-8317-3cdd167ac22c] description = "Invalid boards -> Invalid board: players kept playing after a win" + +[5a84757a-fc86-4328-aec9-a5759e6ed35d] +description = "Invalid boards -> Invalid board: O kept playing after X wins" + +[cf25543d-583a-4656-b9ab-f82dc00a4a02] +description = "Invalid boards -> Invalid board: X kept playing after O wins" diff --git a/exercises/practice/state-of-tic-tac-toe/StateOfTicTacToeTest.php b/exercises/practice/state-of-tic-tac-toe/StateOfTicTacToeTest.php index 65b3579ef..dbc9db939 100644 --- a/exercises/practice/state-of-tic-tac-toe/StateOfTicTacToeTest.php +++ b/exercises/practice/state-of-tic-tac-toe/StateOfTicTacToeTest.php @@ -2,382 +2,466 @@ declare(strict_types=1); +use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\TestCase; class StateOfTicTacToeTest extends TestCase { - private StateOfTicTacToe $stateOfTicTacToe; - public static function setUpBeforeClass(): void { require_once 'StateOfTicTacToe.php'; } - protected function setUp(): void - { - $this->stateOfTicTacToe = new StateOfTicTacToe(); - } - /** * uuid: fe8e9fa9-37af-4d7e-aa24-2f4b8517161a */ + #[TestDox('Won games -> Finished game where X won via left column victory')] public function testWonGamesFinishedGameWhereXWonViaLeftColumnVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XOO", "X ", "X " ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: 96c30df5-ae23-4cf6-bf09-5ef056dddea1 */ + #[TestDox('Won games -> Finished game where X won via middle column victory')] public function testWonGameFinishedGameWhereXWonViaMiddleColumnVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "OXO", " X ", " X " ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: 0d7a4b0a-2afd-4a75-8389-5fb88ab05eda */ + #[TestDox('Won games -> Finished game where X won via right column victory')] public function testWonGameFinishedGameWhereXWonViaRightColumnVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "OOX", " X", " X" ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: bd1007c0-ec5d-4c60-bb9f-1a4f22177d51 */ + #[TestDox('Won games -> Finished game where O won via left column victory')] public function testWonGamesFinishedGameWhereOWonViaLeftColumnVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "OXX", "OX ", "O " ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: c032f800-5735-4354-b1b9-46f14d4ee955 */ + #[TestDox('Won games -> Finished game where O won via middle column victory')] public function testWonGameFinishedGameWhereOWonViaMiddleColumnVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XOX", " OX", " O " ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: 662c8902-c94a-4c4c-9d9c-e8ca513db2b4 */ + #[TestDox('Won games -> Finished game where O won via right column victory')] public function testWonGameFinishedGameWhereOWonViaRightColumnVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XXO", " XO", " O" ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: 2d62121f-7e3a-44a0-9032-0d73e3494941 */ + #[TestDox('Won games -> Finished game where X won via top row victory')] public function testWonGameFinishedWhereXWonViaTopRowVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XXX", "XOO", "O " ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: 346527db-4db9-4a96-b262-d7023dc022b0 */ + #[TestDox('Won games -> Finished game where X won via middle row victory')] public function testWonGameFinishedWhereXWonViaMiddleRowVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "O ", "XXX", " O " ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: a013c583-75f8-4ab2-8d68-57688ff04574 */ + #[TestDox('Won games -> Finished game where X won via bottom row victory')] public function testWonGameFinishedWhereXWonViaBottomRowVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ " OO", "O X", "XXX" ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: 2c08e7d7-7d00-487f-9442-e7398c8f1727 */ + #[TestDox('Won games -> Finished game where O won via top row victory')] public function testWonGameFinishedWhereOWonViaTopRowVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "OOO", "XXO", "XX " ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: bb1d6c62-3e3f-4d1a-9766-f8803c8ed70f */ + #[TestDox('Won games -> Finished game where O won via middle row victory')] public function testWonGameFinishedWhereOWonViaMiddleRowVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XX ", "OOO", "X " ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: 6ef641e9-12ec-44f5-a21c-660ea93907af */ + #[TestDox('Won games -> Finished game where O won via bottom row victory')] public function testWonGameFinishedWhereOWonViaBottomRowVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XOX", " XX", "OOO" ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: ab145b7b-26a7-426c-ab71-bf418cd07f81 */ + #[TestDox('Won games -> Finished game where X won via falling diagonal victory')] public function testWonGameFinishedWhereXWonViaFallingDiagonalVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XOO", " X ", " X" ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: 7450caab-08f5-4f03-a74b-99b98c4b7a4b */ + #[TestDox('Won games -> Finished game where X won via rising diagonal victory')] public function testWonGameFinishedWhereXWonViaRisingDiagonalVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "O X", "OX ", "X " ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: c2a652ee-2f93-48aa-a710-a70cd2edce61 */ + #[TestDox('Won games -> Finished game where O won via falling diagonal victory')] public function testWonGameFinishedWhereOWonViaFallingDiagonalVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "OXX", "OOX", "X O" ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: 5b20ceea-494d-4f0c-a986-b99efc163bcf */ + #[TestDox('Won games -> Finished game where O won via rising diagonal victory')] public function testWonGameFinishedWhereOWonViaRisingDiagonalVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ " O", " OX", "OXX" ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: 035a49b9-dc35-47d3-9d7c-de197161b9d4 */ + #[TestDox('Won games -> Finished game where X won via a row and a column victory')] public function testWonGameFinishedGameWhereXWonViaARowAndAColumnVictory(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XXX", "XOO", "XOO" ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: e5dfdeb0-d2bf-4b5a-b307-e673f69d4a53 */ + #[TestDox('Won games -> Finished game where X won via two diagonal victories')] public function testWonGameFinishedGameWhereXWonViaTwoDiagonalVictories(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XOX", "OXO", "XOX" ]; - $this->assertEquals(State::Win, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Win, $stateOfTicTacToe->gameState($board)); } /** * uuid: b42ed767-194c-4364-b36e-efbfb3de8788 */ - public function testDrawGame(): void + #[TestDox('Drawn games -> Draw')] + public function testDrawnGamesDraw(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XOX", "XXO", "OXO" ]; - $this->assertEquals(State::Draw, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Draw, $stateOfTicTacToe->gameState($board)); } /** * uuid: 227a76b2-0fef-4e16-a4bd-8f9d7e4c3b13 */ - public function testAnotherDrawGame(): void + #[TestDox('Drawn games -> Another draw')] + public function testDrawnGamesAnotherDraw(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XXO", "OXX", "XOO" ]; - $this->assertEquals(State::Draw, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Draw, $stateOfTicTacToe->gameState($board)); } /** * uuid: 4d93f15c-0c40-43d6-b966-418b040012a9 */ - public function testOngoingGameOneMoveIn(): void + #[TestDox('Ongoing games -> Ongoing game: one move in')] + public function testOngoingGamesOngoingGameOneMoveIn(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ " ", "X ", " " ]; - $this->assertEquals(State::Ongoing, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Ongoing, $stateOfTicTacToe->gameState($board)); } /** * uuid: c407ae32-4c44-4989-b124-2890cf531f19 */ - public function testOngoingGameTwoMovesIn(): void + #[TestDox('Ongoing games -> Ongoing game: two moves in')] + public function testOngoingGamesOngoingGameTwoMovesIn(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "O ", " X ", " " ]; - $this->assertEquals(State::Ongoing, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Ongoing, $stateOfTicTacToe->gameState($board)); } /** * uuid: 199b7a8d-e2b6-4526-a85e-78b416e7a8a9 */ - public function testOngoingGameFiveMovesIn(): void + #[TestDox('Ongoing games -> Ongoing game: five moves in')] + public function testOngoingGamesOngoingGameFiveMovesIn(): void { + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "X ", " XO", "OX " ]; - $this->assertEquals(State::Ongoing, $this->stateOfTicTacToe->gameState($board)); + $this->assertEquals(State::Ongoing, $stateOfTicTacToe->gameState($board)); } /** * uuid: 1670145b-1e3d-4269-a7eb-53cd327b302e */ - public function testInvalidBoardsXWentTwice(): void + #[TestDox('Invalid boards -> Invalid board: X went twice')] + public function testInvalidBoardsInvalidBoardXWentTwice(): void { $this->expectException(RuntimeException::class); $this->expectExceptionMessage("Wrong turn order: X went twice"); + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XX ", " ", " " ]; - $this->stateOfTicTacToe->gameState($board); + $stateOfTicTacToe->gameState($board); } /** * uuid: 47c048e8-b404-4bcf-9e51-8acbb3253f3b */ - public function testInvalidBoardOStarted(): void + #[TestDox('nvalid boards -> Invalid board: O started')] + public function testInvalidBoardsInvalidBoardOStarted(): void { $this->expectException(RuntimeException::class); $this->expectExceptionMessage("Wrong turn order: O started"); + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "OOX", " ", " " ]; - $this->stateOfTicTacToe->gameState($board); + $stateOfTicTacToe->gameState($board); } /** * uuid: 6c1920f2-ab5c-4648-a0c9-997414dda5eb */ - public function testInvalidBoard(): void + #[TestDox('Invalid boards -> Invalid board: X won and O kept playing')] + public function testInvalidBoardsInvalidBoardXWonAndOKeptPlaying(): void { $this->expectException(RuntimeException::class); $this->expectExceptionMessage("Impossible board: game should have ended after the game was won"); + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XXX", "OOO", " " ]; - $this->stateOfTicTacToe->gameState($board); + $stateOfTicTacToe->gameState($board); } /** * uuid: 4801cda2-f5b7-4c36-8317-3cdd167ac22c */ - public function testInvalidBoardPlayersKeptPlayingAfterAWin(): void + #[TestDox('Invalid boards -> Invalid board: players kept playing after a win')] + public function testInvalidBoardsInvalidBoardPlayersKeptPlayingAfterAWin(): void { $this->expectException(RuntimeException::class); $this->expectExceptionMessage("Impossible board: game should have ended after the game was won"); + $stateOfTicTacToe = new StateOfTicTacToe(); $board = [ "XXX", "OOO", "XOX" ]; - $this->stateOfTicTacToe->gameState($board); + $stateOfTicTacToe->gameState($board); + } + + /** + * uuid: 5a84757a-fc86-4328-aec9-a5759e6ed35d + */ + #[TestDox('Invalid boards -> Invalid board: O kept playing after X wins')] + public function testInvalidBoardsInvalidBoardOKeptPlayingAfterXWins(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage("Impossible board: game should have ended after the game was won"); + + $stateOfTicTacToe = new StateOfTicTacToe(); + $board = [ + "OO ", + "XXX", + " O " + ]; + $stateOfTicTacToe->gameState($board); + } + + /** + * uuid: cf25543d-583a-4656-b9ab-f82dc00a4a02 + */ + #[TestDox('Invalid boards -> Invalid board: X kept playing after O wins')] + public function testInvalidBoardsInvalidBoardXKeptPlayingAfterOWins(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage("Impossible board: game should have ended after the game was won"); + + $stateOfTicTacToe = new StateOfTicTacToe(); + $board = [ + "XX ", + "OOO", + " XX" + ]; + $stateOfTicTacToe->gameState($board); } } From cd66d2d2182ba2186b721205eabcccfd53f688f3 Mon Sep 17 00:00:00 2001 From: Michael Kramer Date: Sat, 11 Jul 2026 18:49:02 +0200 Subject: [PATCH 4/4] Add missing character --- .../practice/state-of-tic-tac-toe/StateOfTicTacToeTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/state-of-tic-tac-toe/StateOfTicTacToeTest.php b/exercises/practice/state-of-tic-tac-toe/StateOfTicTacToeTest.php index dbc9db939..ba4ffc09f 100644 --- a/exercises/practice/state-of-tic-tac-toe/StateOfTicTacToeTest.php +++ b/exercises/practice/state-of-tic-tac-toe/StateOfTicTacToeTest.php @@ -378,7 +378,7 @@ public function testInvalidBoardsInvalidBoardXWentTwice(): void /** * uuid: 47c048e8-b404-4bcf-9e51-8acbb3253f3b */ - #[TestDox('nvalid boards -> Invalid board: O started')] + #[TestDox('Invalid boards -> Invalid board: O started')] public function testInvalidBoardsInvalidBoardOStarted(): void { $this->expectException(RuntimeException::class);