From 3dff61d3510825052edc155e27dd78c8a770b4b6 Mon Sep 17 00:00:00 2001 From: Oliver Klee Date: Tue, 11 Feb 2025 20:24:43 +0100 Subject: [PATCH 1/3] [TASK] Add tests for the exceptions Part of #757 --- tests/Unit/Parsing/OutputExceptionTest.php | 67 +++++++ tests/Unit/Parsing/SourceExceptionTest.php | 67 +++++++ .../Parsing/UnexpectedEOFExceptionTest.php | 168 ++++++++++++++++++ .../Parsing/UnexpectedTokenExceptionTest.php | 168 ++++++++++++++++++ 4 files changed, 470 insertions(+) create mode 100644 tests/Unit/Parsing/OutputExceptionTest.php create mode 100644 tests/Unit/Parsing/SourceExceptionTest.php create mode 100644 tests/Unit/Parsing/UnexpectedEOFExceptionTest.php create mode 100644 tests/Unit/Parsing/UnexpectedTokenExceptionTest.php diff --git a/tests/Unit/Parsing/OutputExceptionTest.php b/tests/Unit/Parsing/OutputExceptionTest.php new file mode 100644 index 00000000..6ce52e87 --- /dev/null +++ b/tests/Unit/Parsing/OutputExceptionTest.php @@ -0,0 +1,67 @@ +getMessage()); + } + + /** + * @test + */ + public function getLineNoByDefaultReturnsZero(): void + { + $exception = new OutputException('foo'); + + self::assertSame(0, $exception->getLineNo()); + } + + /** + * @test + */ + public function getLineNoReturnsLineNumberProvidedToConstructor(): void + { + $lineNumber = 17; + $exception = new OutputException('foo', $lineNumber); + + self::assertSame($lineNumber, $exception->getLineNo()); + } + + /** + * @test + */ + public function getMessageForLineNumberProvidedIncludesMessage(): void + { + $lineNumber = 17; + $exception = new OutputException('foo', $lineNumber); + + self::assertStringContainsString(' [line no: ' . $lineNumber . ']', $exception->getMessage()); + } + + /** + * @test + */ + public function canBeThrown(): void + { + $this->expectException(OutputException::class); + + throw new OutputException('foo'); + } +} diff --git a/tests/Unit/Parsing/SourceExceptionTest.php b/tests/Unit/Parsing/SourceExceptionTest.php new file mode 100644 index 00000000..8e9a0285 --- /dev/null +++ b/tests/Unit/Parsing/SourceExceptionTest.php @@ -0,0 +1,67 @@ +getMessage()); + } + + /** + * @test + */ + public function getLineNoByDefaultReturnsZero(): void + { + $exception = new SourceException('foo'); + + self::assertSame(0, $exception->getLineNo()); + } + + /** + * @test + */ + public function getLineNoReturnsLineNumberProvidedToConstructor(): void + { + $lineNumber = 17; + $exception = new SourceException('foo', $lineNumber); + + self::assertSame($lineNumber, $exception->getLineNo()); + } + + /** + * @test + */ + public function getMessageForLineNumberProvidedIncludesMessage(): void + { + $lineNumber = 17; + $exception = new SourceException('foo', $lineNumber); + + self::assertStringContainsString(' [line no: ' . $lineNumber . ']', $exception->getMessage()); + } + + /** + * @test + */ + public function canBeThrown(): void + { + $this->expectException(SourceException::class); + + throw new SourceException('foo'); + } +} diff --git a/tests/Unit/Parsing/UnexpectedEOFExceptionTest.php b/tests/Unit/Parsing/UnexpectedEOFExceptionTest.php new file mode 100644 index 00000000..fe5bb5c2 --- /dev/null +++ b/tests/Unit/Parsing/UnexpectedEOFExceptionTest.php @@ -0,0 +1,168 @@ +getLineNo()); + } + + /** + * @test + */ + public function getLineNoReturnsLineNumberProvidedToConstructor(): void + { + $lineNumber = 17; + $exception = new UnexpectedEOFException('expected', 'found', 'literal', $lineNumber); + + self::assertSame($lineNumber, $exception->getLineNo()); + } + + /** + * @test + */ + public function getMessageForLineNumberProvidedIncludesMessage(): void + { + $lineNumber = 17; + $exception = new UnexpectedEOFException('expected', 'found', 'literal', $lineNumber); + + self::assertStringContainsString(' [line no: ' . $lineNumber . ']', $exception->getMessage()); + } + + /** + * @test + */ + public function canBeThrown(): void + { + $this->expectException(UnexpectedEOFException::class); + + throw new UnexpectedEOFException('expected', 'found'); + } + + /** + * @test + */ + public function messageByDefaultRefersToTokenNotFound(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedEOFException($expected, $found); + + $expectedMessage = 'Token “' . $expected . '” (literal) not found. Got “' . $found . '”.'; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForInvalidMatchTypeRefersToTokenNotFound(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedEOFException($expected, $found, 'coding'); + + $expectedMessage = 'Token “' . $expected . '” (coding) not found. Got “' . $found . '”.'; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForLiteralMatchTypeRefersToTokenNotFound(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedEOFException($expected, $found, 'literal'); + + $expectedMessage = 'Token “' . $expected . '” (literal) not found. Got “' . $found . '”.'; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForSearchMatchTypeRefersToNoResults(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedEOFException($expected, $found, 'search'); + + $expectedMessage = 'Search for “' . $expected . '” returned no results. Context: “' . $found . '”.'; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForCountMatchTypeRefersToNumberOfCharacters(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedEOFException($expected, $found, 'count'); + + $expectedMessage = 'Next token was expected to have ' . $expected . ' chars. Context: “' . $found . '”.'; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForIdentifierMatchTypeRefersToIdentifier(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedEOFException($expected, $found, 'identifier'); + + $expectedMessage = 'Identifier expected. Got “' . $found . '”'; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForCustomMatchTypeMentionsExpectedAndFound(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedEOFException($expected, $found, 'custom'); + + $expectedMessage = $expected . ' ' . $found; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForCustomMatchTypeTrimsMessage(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedEOFException(' ' . $expected, $found . ' ', 'custom'); + + $expectedMessage = $expected . ' ' . $found; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } +} diff --git a/tests/Unit/Parsing/UnexpectedTokenExceptionTest.php b/tests/Unit/Parsing/UnexpectedTokenExceptionTest.php new file mode 100644 index 00000000..43daddfc --- /dev/null +++ b/tests/Unit/Parsing/UnexpectedTokenExceptionTest.php @@ -0,0 +1,168 @@ +getLineNo()); + } + + /** + * @test + */ + public function getLineNoReturnsLineNumberProvidedToConstructor(): void + { + $lineNumber = 17; + $exception = new UnexpectedTokenException('expected', 'found', 'literal', $lineNumber); + + self::assertSame($lineNumber, $exception->getLineNo()); + } + + /** + * @test + */ + public function getMessageForLineNumberProvidedIncludesMessage(): void + { + $lineNumber = 17; + $exception = new UnexpectedTokenException('expected', 'found', 'literal', $lineNumber); + + self::assertStringContainsString(' [line no: ' . $lineNumber . ']', $exception->getMessage()); + } + + /** + * @test + */ + public function canBeThrown(): void + { + $this->expectException(UnexpectedTokenException::class); + + throw new UnexpectedTokenException('expected', 'found'); + } + + /** + * @test + */ + public function messageByDefaultRefersToTokenNotFound(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedTokenException($expected, $found); + + $expectedMessage = 'Token “' . $expected . '” (literal) not found. Got “' . $found . '”.'; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForInvalidMatchTypeRefersToTokenNotFound(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedTokenException($expected, $found, 'coding'); + + $expectedMessage = 'Token “' . $expected . '” (coding) not found. Got “' . $found . '”.'; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForLiteralMatchTypeRefersToTokenNotFound(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedTokenException($expected, $found, 'literal'); + + $expectedMessage = 'Token “' . $expected . '” (literal) not found. Got “' . $found . '”.'; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForSearchMatchTypeRefersToNoResults(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedTokenException($expected, $found, 'search'); + + $expectedMessage = 'Search for “' . $expected . '” returned no results. Context: “' . $found . '”.'; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForCountMatchTypeRefersToNumberOfCharacters(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedTokenException($expected, $found, 'count'); + + $expectedMessage = 'Next token was expected to have ' . $expected . ' chars. Context: “' . $found . '”.'; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForIdentifierMatchTypeRefersToIdentifier(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedTokenException($expected, $found, 'identifier'); + + $expectedMessage = 'Identifier expected. Got “' . $found . '”'; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForCustomMatchTypeMentionsExpectedAndFound(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedTokenException($expected, $found, 'custom'); + + $expectedMessage = $expected . ' ' . $found; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } + + /** + * @test + */ + public function messageForCustomMatchTypeTrimsMessage(): void + { + $expected = 'tea'; + $found = 'coffee'; + + $exception = new UnexpectedTokenException(' ' . $expected, $found . ' ', 'custom'); + + $expectedMessage = $expected . ' ' . $found; + self::assertStringContainsString($expectedMessage, $exception->getMessage()); + } +} From a6cb5c820897d6fe3e002905d10f5c143f511229 Mon Sep 17 00:00:00 2001 From: Oliver Klee Date: Thu, 13 Feb 2025 10:16:59 +0100 Subject: [PATCH 2/3] Add tests for the class hierarchies --- tests/Unit/Parsing/OutputExceptionTest.php | 9 +++++++++ tests/Unit/Parsing/UnexpectedEOFExceptionTest.php | 9 +++++++++ tests/Unit/Parsing/UnexpectedTokenExceptionTest.php | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/tests/Unit/Parsing/OutputExceptionTest.php b/tests/Unit/Parsing/OutputExceptionTest.php index 6ce52e87..39fd6262 100644 --- a/tests/Unit/Parsing/OutputExceptionTest.php +++ b/tests/Unit/Parsing/OutputExceptionTest.php @@ -6,12 +6,21 @@ use PHPUnit\Framework\TestCase; use Sabberworm\CSS\Parsing\OutputException; +use Sabberworm\CSS\Parsing\SourceException; /** * @covers \Sabberworm\CSS\Parsing\OutputException */ final class OutputExceptionTest extends TestCase { + /** + * @test + */ + public function extendsSourceException(): void + { + self::assertInstanceOf(SourceException::class, new OutputException('foo')); + } + /** * @test */ diff --git a/tests/Unit/Parsing/UnexpectedEOFExceptionTest.php b/tests/Unit/Parsing/UnexpectedEOFExceptionTest.php index fe5bb5c2..b153d6ac 100644 --- a/tests/Unit/Parsing/UnexpectedEOFExceptionTest.php +++ b/tests/Unit/Parsing/UnexpectedEOFExceptionTest.php @@ -6,12 +6,21 @@ use PHPUnit\Framework\TestCase; use Sabberworm\CSS\Parsing\UnexpectedEOFException; +use Sabberworm\CSS\Parsing\UnexpectedTokenException; /** * @covers \Sabberworm\CSS\Parsing\UnexpectedEOFException */ final class UnexpectedEOFExceptionTest extends TestCase { + /** + * @test + */ + public function extendsUnexpectedTokenException(): void + { + self::assertInstanceOf(UnexpectedTokenException::class, new UnexpectedEOFException('expected', 'found')); + } + /** * @test */ diff --git a/tests/Unit/Parsing/UnexpectedTokenExceptionTest.php b/tests/Unit/Parsing/UnexpectedTokenExceptionTest.php index 43daddfc..d7fdb733 100644 --- a/tests/Unit/Parsing/UnexpectedTokenExceptionTest.php +++ b/tests/Unit/Parsing/UnexpectedTokenExceptionTest.php @@ -5,6 +5,7 @@ namespace Sabberworm\CSS\Tests\Unit\Parsing; use PHPUnit\Framework\TestCase; +use Sabberworm\CSS\Parsing\SourceException; use Sabberworm\CSS\Parsing\UnexpectedTokenException; /** @@ -12,6 +13,14 @@ */ final class UnexpectedTokenExceptionTest extends TestCase { + /** + * @test + */ + public function extendsSourceException(): void + { + self::assertInstanceOf(SourceException::class, new UnexpectedTokenException('expected', 'found')); + } + /** * @test */ From d1b22cbc00feeec5074f3d4035cc79365ccf79fc Mon Sep 17 00:00:00 2001 From: Oliver Klee Date: Thu, 13 Feb 2025 10:22:27 +0100 Subject: [PATCH 3/3] Fix test names --- tests/Unit/Parsing/OutputExceptionTest.php | 2 +- tests/Unit/Parsing/SourceExceptionTest.php | 2 +- tests/Unit/Parsing/UnexpectedEOFExceptionTest.php | 2 +- tests/Unit/Parsing/UnexpectedTokenExceptionTest.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Unit/Parsing/OutputExceptionTest.php b/tests/Unit/Parsing/OutputExceptionTest.php index 39fd6262..d3409aa4 100644 --- a/tests/Unit/Parsing/OutputExceptionTest.php +++ b/tests/Unit/Parsing/OutputExceptionTest.php @@ -56,7 +56,7 @@ public function getLineNoReturnsLineNumberProvidedToConstructor(): void /** * @test */ - public function getMessageForLineNumberProvidedIncludesMessage(): void + public function getMessageWithLineNumberProvidedIncludesLineNumber(): void { $lineNumber = 17; $exception = new OutputException('foo', $lineNumber); diff --git a/tests/Unit/Parsing/SourceExceptionTest.php b/tests/Unit/Parsing/SourceExceptionTest.php index 8e9a0285..b497ff52 100644 --- a/tests/Unit/Parsing/SourceExceptionTest.php +++ b/tests/Unit/Parsing/SourceExceptionTest.php @@ -47,7 +47,7 @@ public function getLineNoReturnsLineNumberProvidedToConstructor(): void /** * @test */ - public function getMessageForLineNumberProvidedIncludesMessage(): void + public function getMessageWithLineNumberProvidedIncludesLineNumber(): void { $lineNumber = 17; $exception = new SourceException('foo', $lineNumber); diff --git a/tests/Unit/Parsing/UnexpectedEOFExceptionTest.php b/tests/Unit/Parsing/UnexpectedEOFExceptionTest.php index b153d6ac..929609ef 100644 --- a/tests/Unit/Parsing/UnexpectedEOFExceptionTest.php +++ b/tests/Unit/Parsing/UnexpectedEOFExceptionTest.php @@ -45,7 +45,7 @@ public function getLineNoReturnsLineNumberProvidedToConstructor(): void /** * @test */ - public function getMessageForLineNumberProvidedIncludesMessage(): void + public function getMessageWithLineNumberProvidedIncludesLineNumber(): void { $lineNumber = 17; $exception = new UnexpectedEOFException('expected', 'found', 'literal', $lineNumber); diff --git a/tests/Unit/Parsing/UnexpectedTokenExceptionTest.php b/tests/Unit/Parsing/UnexpectedTokenExceptionTest.php index d7fdb733..e5c7a64d 100644 --- a/tests/Unit/Parsing/UnexpectedTokenExceptionTest.php +++ b/tests/Unit/Parsing/UnexpectedTokenExceptionTest.php @@ -45,7 +45,7 @@ public function getLineNoReturnsLineNumberProvidedToConstructor(): void /** * @test */ - public function getMessageForLineNumberProvidedIncludesMessage(): void + public function getMessageWithLineNumberProvidedIncludesLineNumber(): void { $lineNumber = 17; $exception = new UnexpectedTokenException('expected', 'found', 'literal', $lineNumber);