diff --git a/.appveyor.yml b/.appveyor.yml index abb6aefe0f..c84dc3372c 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,6 +1,6 @@ version: 2.x-{build} build: false -clone_depth: 2 +clone_depth: 50 clone_folder: c:\projects\sentry-php skip_branch_with_pr: true image: Visual Studio 2019 @@ -8,22 +8,28 @@ image: Visual Studio 2019 environment: matrix: - PHP_VERSION: 7.2 - XDEBUG_VERSION: 2.9.2-7.2-vc15-nts + XDEBUG_VERSION: 3.0.1-7.2-vc15-nts DEPENDENCIES: lowest - PHP_VERSION: 7.2 - XDEBUG_VERSION: 2.9.2-7.2-vc15-nts + XDEBUG_VERSION: 3.0.1-7.2-vc15-nts DEPENDENCIES: highest - PHP_VERSION: 7.3 - XDEBUG_VERSION: 2.9.2-7.3-vc15-nts + XDEBUG_VERSION: 3.0.1-7.3-vc15-nts DEPENDENCIES: lowest - PHP_VERSION: 7.3 - XDEBUG_VERSION: 2.9.2-7.3-vc15-nts + XDEBUG_VERSION: 3.0.1-7.3-vc15-nts DEPENDENCIES: highest - PHP_VERSION: 7.4 - XDEBUG_VERSION: 2.9.2-7.4-vc15-nts + XDEBUG_VERSION: 3.0.1-7.4-vc15-nts DEPENDENCIES: lowest - PHP_VERSION: 7.4 - XDEBUG_VERSION: 2.9.2-7.4-vc15-nts + XDEBUG_VERSION: 3.0.1-7.4-vc15-nts + DEPENDENCIES: highest + - PHP_VERSION: 8.0 + XDEBUG_VERSION: 3.0.1-8.0-vs16-nts + DEPENDENCIES: lowest + - PHP_VERSION: 8.0 + XDEBUG_VERSION: 3.0.1-8.0-vs16-nts DEPENDENCIES: highest matrix: @@ -52,16 +58,13 @@ install: - IF %INSTALL_PHP%==1 echo extension=php_mbstring.dll >> php.ini - IF %INSTALL_PHP%==1 echo extension=php_openssl.dll >> php.ini - IF %INSTALL_PHP%==1 echo zend_extension=C:\php\ext\php_xdebug.dll >> php.ini - - IF %INSTALL_PHP%==1 echo xdebug.overload_var_dump=0 >> php.ini - - IF %INSTALL_PHP%==1 echo xdebug.collect_includes=0 >> php.ini - - IF %INSTALL_PHP%==1 echo xdebug.dump_globals=0 >> php.ini - - IF %INSTALL_PHP%==1 echo xdebug.collect_vars=0 >> php.ini - - IF %INSTALL_PHP%==1 echo xdebug.extended_info=0 >> php.ini + - IF %INSTALL_PHP%==1 echo xdebug.mode=coverage >> php.ini - cd C:\projects\sentry-php - - IF NOT EXIST composer.phar appveyor-retry appveyor DownloadFile https://github.com/composer/composer/releases/download/1.9.3/composer.phar + - IF NOT EXIST composer.phar appveyor-retry appveyor DownloadFile https://github.com/composer/composer/releases/download/2.0.8/composer.phar - php composer.phar self-update - - IF %DEPENDENCIES%==lowest php composer.phar update --no-progress --no-interaction --no-suggest --ansi --prefer-lowest --prefer-dist - - IF %DEPENDENCIES%==highest php composer.phar update --no-progress --no-interaction --no-suggest --ansi --prefer-dist + - IF %PHP_VERSION%==8.0 php composer.phar remove --dev friendsofphp/php-cs-fixer --no-update --no-interaction + - IF %DEPENDENCIES%==lowest php composer.phar update --no-progress --no-interaction --ansi --prefer-lowest --prefer-dist + - IF %DEPENDENCIES%==highest php composer.phar update --no-progress --no-interaction --ansi --prefer-dist test_script: - cd C:\projects\sentry-php diff --git a/.gitattributes b/.gitattributes index ec85a1b1cc..c067dc5ae7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -16,9 +16,9 @@ /.editorconfig export-ignore /.gitattributes export-ignore /.gitignore export-ignore -/.php_cs export-ignore -/.scrutinizer.yml export-ignore +/.php_cs.dist export-ignore /.travis.yml export-ignore /Makefile export-ignore /phpstan.neon export-ignore /phpunit.xml.dist export-ignore +/psalm.xml.dist export-ignore diff --git a/.gitignore b/.gitignore index 75ef0bad07..25a58fe9cb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ package.xml /vendor .idea .php_cs.cache +.phpunit.result.cache docs/_build tests/clover.xml diff --git a/.travis.yml b/.travis.yml index ebe4ca7e91..98aadecf0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ php: - 7.2 - 7.3 - 7.4 + - 8.0 env: - dependencies=highest @@ -34,11 +35,12 @@ jobs: script: composer psalm install: + - if [ "$TRAVIS_PHP_VERSION" = "8.0" ]; then composer remove --dev friendsofphp/php-cs-fixer --no-update --no-interaction; fi; - if [ "$dependencies" = "lowest" ]; then composer update --no-interaction --no-suggest --prefer-lowest --prefer-dist; fi; - if [ "$dependencies" = "highest" ]; then composer update --no-interaction --no-suggest --prefer-dist; fi; script: >- - vendor/bin/phpunit --coverage-clover=build/coverage-report.xml && + XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-clover=build/coverage-report.xml && bash <(curl -s https://codecov.io/bash) -f build/coverage-report.xml notifications: diff --git a/CHANGELOG.md b/CHANGELOG.md index c6d67670d7..530b4ff610 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## 3.1.0 (2020-12-01) +- Add support for PHP 8.0 (#1087) +- Change the error handling for silenced fatal errors using `@` to use a mask check in order to be php 8 compatible (#1141) +- Update the `guzzlehttp/promises` package to the minimum required version compatible with PHP 8 (#1144) +- Update the `symfony/options-resolver` package to the minimum required version compatible with PHP 8 (#1144) - Fix capturing of the request body in the `RequestIntegration` integration (#1139) - Deprecate `SpanContext::fromTraceparent()` in favor of `TransactionContext::fromSentryTrace()` (#1134) - Allow setting custom data on the sampling context by passing it as 2nd argument of the `startTransaction()` function (#1134) diff --git a/composer.json b/composer.json index 09d992ceb4..751f71577b 100644 --- a/composer.json +++ b/composer.json @@ -20,10 +20,10 @@ } ], "require": { - "php": "^7.2", + "php": "^7.2|^8.0", "ext-json": "*", "ext-mbstring": "*", - "guzzlehttp/promises": "^1.3", + "guzzlehttp/promises": "^1.4", "guzzlehttp/psr7": "^1.7", "jean85/pretty-package-versions": "^1.5", "ocramius/package-versions": "^1.8", @@ -35,7 +35,7 @@ "psr/http-factory": "^1.0", "psr/http-message-implementation": "^1.0", "psr/log": "^1.0", - "symfony/options-resolver": "^3.4.4|^4.0|^5.0", + "symfony/options-resolver": "^3.4.43|^4.4.11|^5.0.11", "symfony/polyfill-php80": "^1.17", "symfony/polyfill-uuid": "^1.13.1" }, @@ -43,13 +43,14 @@ "friendsofphp/php-cs-fixer": "^2.16", "http-interop/http-factory-guzzle": "^1.0", "monolog/monolog": "^1.3|^2.0", + "nikic/php-parser": "^4.10.3", "php-http/mock-client": "^1.3", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^0.12", "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.5.18", - "symfony/phpunit-bridge": "^5.1", - "vimeo/psalm": "^3.4" + "phpunit/phpunit": "^8.5.13|^9.4", + "symfony/phpunit-bridge": "^5.2", + "vimeo/psalm": "^3.4|^4.2" }, "suggest": { "monolog/monolog": "Allow sending log messages to Sentry by using the included Monolog handler." diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8c633d455d..0f5d147423 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,10 +1,11 @@ - @@ -17,6 +18,12 @@ + + + src + + + src diff --git a/psalm.xml.dist b/psalm.xml.dist index 34d01006db..e1cbbfde23 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -34,7 +34,6 @@ - diff --git a/src/ErrorHandler.php b/src/ErrorHandler.php index 95493f447d..af00bf53d5 100644 --- a/src/ErrorHandler.php +++ b/src/ErrorHandler.php @@ -265,7 +265,7 @@ public function addExceptionHandlerListener(callable $listener): void */ private function handleError(int $level, string $message, string $file, int $line, ?array $errcontext = []): bool { - if (0 === error_reporting()) { + if (0 === (error_reporting() & $level)) { $errorAsException = new SilencedErrorException(self::ERROR_LEVELS_DESCRIPTION[$level] . ': ' . $message, 0, $level, $file, $line); } else { $errorAsException = new \ErrorException(self::ERROR_LEVELS_DESCRIPTION[$level] . ': ' . $message, 0, $level, $file, $line); diff --git a/src/Exception/ExceptionInterface.php b/src/Exception/ExceptionInterface.php index b957bd2e10..d4be5c56dc 100644 --- a/src/Exception/ExceptionInterface.php +++ b/src/Exception/ExceptionInterface.php @@ -8,6 +8,8 @@ * This interface must be implemented by all exception classes of this library. * * @author Stefano Arlandini + * + * @deprecated since version 3.1, to be removed in 4.0 */ interface ExceptionInterface { diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php index 711a78d68a..745f0e82bb 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Exception/InvalidArgumentException.php @@ -9,6 +9,8 @@ * the expected value. * * @author Stefano Arlandini + * + * @deprecated since version 3.1, to be removed in 4.0 */ class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface { diff --git a/tests/BreadcrumbTest.php b/tests/BreadcrumbTest.php index ec0684d126..7499acb422 100644 --- a/tests/BreadcrumbTest.php +++ b/tests/BreadcrumbTest.php @@ -12,21 +12,19 @@ */ final class BreadcrumbTest extends TestCase { - /** - * @expectedException \Sentry\Exception\InvalidArgumentException - * @expectedExceptionMessage The value of the $level argument must be one of the Breadcrumb::LEVEL_* constants. - */ public function testConstructorThrowsOnInvalidLevel(): void { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('The value of the $level argument must be one of the Breadcrumb::LEVEL_* constants.'); + new Breadcrumb('foo', 'bar', 'baz'); } - /** - * @expectedException \Sentry\Exception\InvalidArgumentException - * @expectedExceptionMessage The value of the $level argument must be one of the Breadcrumb::LEVEL_* constants. - */ - public function testSetLevelThrowsOnInvalidLevel(): void + public function testWithLevelThrowsOnInvalidLevel(): void { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('The value of the $level argument must be one of the Breadcrumb::LEVEL_* constants.'); + $breadcrumb = new Breadcrumb(Breadcrumb::LEVEL_INFO, Breadcrumb::TYPE_USER, 'foo'); $breadcrumb->withLevel('bar'); } diff --git a/tests/ClientBuilderTest.php b/tests/ClientBuilderTest.php index 7e95f8caa0..2f123c9b22 100644 --- a/tests/ClientBuilderTest.php +++ b/tests/ClientBuilderTest.php @@ -13,6 +13,7 @@ use Sentry\Options; use Sentry\Transport\HttpTransport; use Sentry\Transport\NullTransport; +use Sentry\Transport\TransportInterface; final class ClientBuilderTest extends TestCase { @@ -20,7 +21,7 @@ public function testHttpTransportIsUsedWhenServerIsConfigured(): void { $clientBuilder = ClientBuilder::create(['dsn' => 'http://public:secret@example.com/sentry/1']); - $transport = $this->getObjectAttribute($clientBuilder->getClient(), 'transport'); + $transport = $this->getTransport($clientBuilder->getClient()); $this->assertInstanceOf(HttpTransport::class, $transport); } @@ -29,7 +30,7 @@ public function testNullTransportIsUsedWhenNoServerIsConfigured(): void { $clientBuilder = new ClientBuilder(); - $transport = $this->getObjectAttribute($clientBuilder->getClient(), 'transport'); + $transport = $this->getTransport($clientBuilder->getClient()); $this->assertInstanceOf(NullTransport::class, $transport); } @@ -84,6 +85,17 @@ public function testCreateWithNoOptionsIsTheSameAsDefaultOptions(): void ClientBuilder::create([]) ); } + + private function getTransport(Client $client): TransportInterface + { + $property = new \ReflectionProperty(Client::class, 'transport'); + + $property->setAccessible(true); + $value = $property->getValue($client); + $property->setAccessible(false); + + return $value; + } } final class StubIntegration implements IntegrationInterface diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 137b01aeec..0e5aa45af2 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -6,8 +6,8 @@ use GuzzleHttp\Promise\FulfilledPromise; use GuzzleHttp\Promise\PromiseInterface; -use PHPUnit\Framework\MockObject\Matcher\Invocation; use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\MockObject\Rule\InvocationOrder; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; use Sentry\Client; @@ -271,7 +271,7 @@ public function testCaptureLastError(): void $this->assertNotNull($client->captureLastError()); - $this->clearLastError(); + error_clear_last(); } public function testCaptureLastErrorDoesNothingWhenThereIsNoError(): void @@ -280,14 +280,13 @@ public function testCaptureLastErrorDoesNothingWhenThereIsNoError(): void $transport = $this->createMock(TransportInterface::class); $transport->expects($this->never()) ->method('send') - ->with($this->anything()) - ->willReturn(null); + ->with($this->anything()); $client = ClientBuilder::create(['dsn' => 'http://public:secret@example.com/1']) ->setTransportFactory($this->createTransportFactory($transport)) ->getClient(); - $this->clearLastError(); + error_clear_last(); $this->assertNull($client->captureLastError()); } @@ -320,14 +319,13 @@ public function testSendChecksBeforeSendOption(): void /** * @dataProvider processEventDiscardsEventWhenItIsSampledDueToSampleRateOptionDataProvider */ - public function testProcessEventDiscardsEventWhenItIsSampledDueToSampleRateOption(float $sampleRate, Invocation $transportCallInvocationMatcher, Invocation $loggerCallInvocationMatcher): void + public function testProcessEventDiscardsEventWhenItIsSampledDueToSampleRateOption(float $sampleRate, InvocationOrder $transportCallInvocationMatcher, InvocationOrder $loggerCallInvocationMatcher): void { /** @var TransportInterface&MockObject $transport */ $transport = $this->createMock(TransportInterface::class); $transport->expects($transportCallInvocationMatcher) ->method('send') - ->with($this->anything()) - ->willReturn(null); + ->with($this->anything()); /** @var LoggerInterface&MockObject $logger */ $logger = $this->createMock(LoggerInterface::class); @@ -448,20 +446,6 @@ public function testFlush(): void $this->assertTrue($promise->wait()); } - /** - * @see https://github.com/symfony/polyfill/blob/52332f49d18c413699d2dccf465234356f8e0b2c/src/Php70/Php70.php#L52-L61 - */ - private function clearLastError(): void - { - set_error_handler(static function (): bool { - return false; - }); - - @trigger_error(''); - - restore_error_handler(); - } - private function createTransportFactory(TransportInterface $transport): TransportFactoryInterface { return new class($transport) implements TransportFactoryInterface { diff --git a/tests/Serializer/AbstractSerializerTest.php b/tests/Serializer/AbstractSerializerTest.php index 0ec7c17c80..7d421f17e9 100644 --- a/tests/Serializer/AbstractSerializerTest.php +++ b/tests/Serializer/AbstractSerializerTest.php @@ -16,7 +16,7 @@ abstract protected function createSerializer(): AbstractSerializer; /** * This method is only existed because of testSerializeCallable. */ - public static function setUpBeforeClass() + public static function setUpBeforeClass(): void { } @@ -331,7 +331,7 @@ public function testBrokenEncoding(bool $serializeAllObjects): void $input = pack('H*', $key); $result = $this->invokeSerialization($serializer, $input); - $this->assertInternalType('string', $result); + $this->assertIsString($result); if (\function_exists('mb_detect_encoding')) { $this->assertContains(mb_detect_encoding($result), ['ASCII', 'UTF-8']); @@ -354,7 +354,7 @@ public function testLongString(bool $serializeAllObjects): void $input = str_repeat('x', $length); $result = $this->invokeSerialization($serializer, $input); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $this->assertLessThanOrEqual(1024, \strlen($result)); } } @@ -378,7 +378,7 @@ public function testSerializeValueResource(bool $serializeAllObjects): void $result = $this->invokeSerialization($serializer, $resource); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $this->assertSame('Resource stream', $result); } @@ -449,15 +449,15 @@ public function serializableCallableProvider(): array ], [ 'callable' => [TestCase::class, 'setUpBeforeClass'], - 'expected' => 'Callable PHPUnit\\Framework\\TestCase::setUpBeforeClass []', + 'expected' => 'Callable void PHPUnit\\Framework\\TestCase::setUpBeforeClass []', ], [ 'callable' => [$this, 'setUpBeforeClass'], - 'expected' => 'Callable ' . __CLASS__ . '::setUpBeforeClass []', + 'expected' => 'Callable void ' . __CLASS__ . '::setUpBeforeClass []', ], [ 'callable' => [self::class, 'setUpBeforeClass'], - 'expected' => 'Callable ' . __CLASS__ . '::setUpBeforeClass []', + 'expected' => 'Callable void ' . __CLASS__ . '::setUpBeforeClass []', ], [ 'callable' => [SerializerTestObject::class, 'testy'], diff --git a/tests/Serializer/RepresentationSerializerTest.php b/tests/Serializer/RepresentationSerializerTest.php index e2510759cc..8d512caecf 100644 --- a/tests/Serializer/RepresentationSerializerTest.php +++ b/tests/Serializer/RepresentationSerializerTest.php @@ -39,7 +39,7 @@ public function testIntsBecomeStrings(bool $serializeAllObjects): void $result = $serializer->representationSerialize(1); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $this->assertSame('1', $result); } @@ -56,7 +56,7 @@ public function testFloatsBecomeStrings(bool $serializeAllObjects): void $result = $serializer->representationSerialize(1.5); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $this->assertSame('1.5', $result); } @@ -77,7 +77,7 @@ public function testBooleansBecomeStrings(bool $serializeAllObjects): void $result = $serializer->representationSerialize(false); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $this->assertSame('false', $result); } @@ -94,7 +94,7 @@ public function testNullsBecomeString(bool $serializeAllObjects): void $result = $serializer->representationSerialize(null); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $this->assertSame('null', $result); } @@ -111,17 +111,17 @@ public function testSerializeRoundedFloat(bool $serializeAllObjects): void $result = $serializer->representationSerialize((float) 1); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $this->assertSame('1.0', $result); $result = $serializer->representationSerialize(floor(5 / 2)); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $this->assertSame('2.0', $result); $result = $serializer->representationSerialize(floor(12345.678901234)); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $this->assertSame('12345.0', $result); } diff --git a/tests/Serializer/SerializerTest.php b/tests/Serializer/SerializerTest.php index f04e55e001..d8d7e2fd0e 100644 --- a/tests/Serializer/SerializerTest.php +++ b/tests/Serializer/SerializerTest.php @@ -40,7 +40,7 @@ public function testIntsAreInts(bool $serializeAllObjects): void $result = $this->invokeSerialization($serializer, 1); - $this->assertInternalType('integer', $result); + $this->assertIsInt($result); $this->assertSame(1, $result); } @@ -57,7 +57,7 @@ public function testFloats(bool $serializeAllObjects): void $result = $this->invokeSerialization($serializer, 1.5); - $this->assertInternalType('double', $result); + $this->assertIsFloat($result); $this->assertSame(1.5, $result); } @@ -174,7 +174,7 @@ public function testLongStringWithOverwrittenMessageLength(): void $input = str_repeat('x', $length); $result = $this->invokeSerialization($serializer, $input); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $this->assertLessThanOrEqual(500, \strlen($result)); } } diff --git a/tests/SeverityTest.php b/tests/SeverityTest.php index c6c000a4dc..661088cabf 100644 --- a/tests/SeverityTest.php +++ b/tests/SeverityTest.php @@ -9,12 +9,11 @@ final class SeverityTest extends TestCase { - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage The "foo" is not a valid enum value. - */ public function testConstructorThrowsOnInvalidValue(): void { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('The "foo" is not a valid enum value.'); + new Severity('foo'); } diff --git a/tests/StacktraceTest.php b/tests/StacktraceTest.php index b050142763..e3de8fa7e7 100644 --- a/tests/StacktraceTest.php +++ b/tests/StacktraceTest.php @@ -27,7 +27,7 @@ public function testConstructorThrowsIfFramesListIsEmpty(): void public function testConstructorThrowsIfFramesListContainsUnexpectedValue(array $values, string $expectedExceptionMessage): void { $this->expectException(\UnexpectedValueException::class); - $this->expectExceptionMessageRegExp($expectedExceptionMessage); + $this->expectExceptionMessageMatches($expectedExceptionMessage); new Stacktrace($values); } diff --git a/tests/Util/JSONTest.php b/tests/Util/JSONTest.php index 3489182ddb..78b4f6aa2f 100644 --- a/tests/Util/JSONTest.php +++ b/tests/Util/JSONTest.php @@ -5,6 +5,7 @@ namespace Sentry\Tests\Util; use PHPUnit\Framework\TestCase; +use Sentry\Exception\JsonException; use Sentry\Tests\Util\Fixtures\JsonSerializableClass; use Sentry\Tests\Util\Fixtures\SimpleClass; use Sentry\Util\JSON; @@ -98,10 +99,6 @@ public function encodeSubstitutesInvalidUtf8CharactersDataProvider(): \Generator ]; } - /** - * @expectedException \Sentry\Exception\JsonException - * @expectedExceptionMessage Could not encode value into JSON format. Error was: "Type is not supported". - */ public function testEncodeThrowsIfValueIsResource(): void { $resource = fopen('php://memory', 'r'); @@ -110,6 +107,9 @@ public function testEncodeThrowsIfValueIsResource(): void fclose($resource); + $this->expectException(JsonException::class); + $this->expectExceptionMessage('Could not encode value into JSON format. Error was: "Type is not supported".'); + JSON::encode($resource); } @@ -151,12 +151,11 @@ public function decodeDataProvider(): \Generator ]; } - /** - * @expectedException \Sentry\Exception\JsonException - * @expectedExceptionMessage Could not decode value from JSON format. Error was: "Syntax error". - */ public function testDecodeThrowsIfValueIsNotValidJson(): void { + $this->expectException(JsonException::class); + $this->expectExceptionMessage('Could not decode value from JSON format. Error was: "Syntax error".'); + JSON::decode('foo'); } } diff --git a/tests/phpt/error_handler_captures_out_of_memory_fatal_error.phpt b/tests/phpt/error_handler_captures_out_of_memory_fatal_error.phpt index 68e2078797..20cf5ff13b 100644 --- a/tests/phpt/error_handler_captures_out_of_memory_fatal_error.phpt +++ b/tests/phpt/error_handler_captures_out_of_memory_fatal_error.phpt @@ -1,7 +1,7 @@ --TEST-- Test catching out of memory fatal error --INI-- -memory_limit=20M +memory_limit=64M --FILE-- addExceptionHandlerListener(static function (): void { echo 'Exception listener called (it should not have been)' . PHP_EOL; }); -$foo = str_repeat('x', 1024 * 1024 * 30); +$foo = str_repeat('x', 1024 * 1024 * 70); ?> --EXPECTF-- Fatal error: Allowed memory size of %d bytes exhausted (tried to allocate %d bytes) in %s on line %d