diff --git a/tests/Unit/Parsing/OutputExceptionTest.php b/tests/Unit/Parsing/OutputExceptionTest.php new file mode 100644 index 00000000..d3409aa4 --- /dev/null +++ b/tests/Unit/Parsing/OutputExceptionTest.php @@ -0,0 +1,76 @@ +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 getMessageWithLineNumberProvidedIncludesLineNumber(): 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..b497ff52 --- /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 getMessageWithLineNumberProvidedIncludesLineNumber(): 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..929609ef --- /dev/null +++ b/tests/Unit/Parsing/UnexpectedEOFExceptionTest.php @@ -0,0 +1,177 @@ +getLineNo()); + } + + /** + * @test + */ + public function getLineNoReturnsLineNumberProvidedToConstructor(): void + { + $lineNumber = 17; + $exception = new UnexpectedEOFException('expected', 'found', 'literal', $lineNumber); + + self::assertSame($lineNumber, $exception->getLineNo()); + } + + /** + * @test + */ + public function getMessageWithLineNumberProvidedIncludesLineNumber(): 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..e5c7a64d --- /dev/null +++ b/tests/Unit/Parsing/UnexpectedTokenExceptionTest.php @@ -0,0 +1,177 @@ +getLineNo()); + } + + /** + * @test + */ + public function getLineNoReturnsLineNumberProvidedToConstructor(): void + { + $lineNumber = 17; + $exception = new UnexpectedTokenException('expected', 'found', 'literal', $lineNumber); + + self::assertSame($lineNumber, $exception->getLineNo()); + } + + /** + * @test + */ + public function getMessageWithLineNumberProvidedIncludesLineNumber(): 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()); + } +}