diff --git a/composer.json b/composer.json index b25ea980d90..f918f3744bc 100644 --- a/composer.json +++ b/composer.json @@ -63,7 +63,7 @@ }, "require-dev": { "composer/semver": "^3.4", - "phpunit/phpunit": "^9.6", + "phpunit/phpunit": "^11.3", "silverstripe/versioned": "^3", "squizlabs/php_codesniffer": "^3.7", "silverstripe/standards": "^1", diff --git a/tests/php/Control/HTTPRequestTest.php b/tests/php/Control/HTTPRequestTest.php index 93391c12c75..5def189250c 100644 --- a/tests/php/Control/HTTPRequestTest.php +++ b/tests/php/Control/HTTPRequestTest.php @@ -7,11 +7,35 @@ use SilverStripe\Control\Middleware\TrustedProxyMiddleware; use SilverStripe\Control\Session; use SilverStripe\Dev\SapphireTest; +use SilverStripe\Control\Tests\HTTPRequestTest\HTTPRequestTestException; class HTTPRequestTest extends SapphireTest { protected static $fixture_file = null; + /** + * @param callable|null $oldHandler + */ + private $oldHandler = null; + + protected function setup(): void + { + // Use custom error handler to allow the use of expectException() to catch warnings + // which is required in testWildCardWithFurtherParams(). + // PHPUnit does not support expecting warnings + parent::setup(); + $this->oldHandler = set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) { + throw new HTTPRequestTestException($errstr); + }); + } + + protected function tearDown(): void + { + restore_error_handler(); + $this->oldHandler = null; + parent::tearDown(); + } + public function testMatch() { $request = new HTTPRequest("GET", "admin/crm/add"); @@ -55,7 +79,8 @@ public function testWildCardMatch() */ public function testWildCardWithFurtherParams() { - $this->expectWarning(); + $this->expectException(HTTPRequestTestException::class); + $this->expectExceptionMessage('All URL params after wildcard parameter $@ will be ignored'); $request = new HTTPRequest('GET', 'admin/crm/test'); // all parameters after the first wildcard parameter are ignored $request->match('admin/$Action/$@/$Other/$*', true); diff --git a/tests/php/Control/HTTPRequestTest/HTTPRequestTestException.php b/tests/php/Control/HTTPRequestTest/HTTPRequestTestException.php new file mode 100644 index 00000000000..799cfa4d750 --- /dev/null +++ b/tests/php/Control/HTTPRequestTest/HTTPRequestTestException.php @@ -0,0 +1,10 @@ +oldHandler = set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) { + throw new RequestHandlerTestException($errstr); + }); + } + + protected function tearDown(): void + { + restore_error_handler(); + $this->oldHandler = null; + parent::tearDown(); + } + public function provideTestLink(): array { return [ @@ -48,8 +72,8 @@ public function provideTestLink(): array public function testLink(?string $urlSegment, ?string $action, ?string $expected) { if ($urlSegment === null) { - $this->expectWarning(); - $this->expectWarningMessage('Request handler SilverStripe\Control\RequestHandler does not have a url_segment defined. Relying on this link may be an application error'); + $this->expectException(RequestHandlerTestException::class); + $this->expectExceptionMessage('Request handler SilverStripe\Control\RequestHandler does not have a url_segment defined. Relying on this link may be an application error'); } $handler = new RequestHandler(); @@ -73,8 +97,8 @@ public function testLink(?string $urlSegment, ?string $action, ?string $expected public function testAbsoluteLink(?string $urlSegment, ?string $action, ?string $expected) { if ($urlSegment === null) { - $this->expectWarning(); - $this->expectWarningMessage('Request handler SilverStripe\Control\RequestHandler does not have a url_segment defined. Relying on this link may be an application error'); + $this->expectException(RequestHandlerTestException::class); + $this->expectExceptionMessage('Request handler SilverStripe\Control\RequestHandler does not have a url_segment defined. Relying on this link may be an application error'); } $handler = new RequestHandler(); diff --git a/tests/php/Control/RequestHandlerTest/RequestHandlerTestExcpetion.php b/tests/php/Control/RequestHandlerTest/RequestHandlerTestExcpetion.php new file mode 100644 index 00000000000..b23a3d53a80 --- /dev/null +++ b/tests/php/Control/RequestHandlerTest/RequestHandlerTestExcpetion.php @@ -0,0 +1,10 @@ +noticesWereEnabled = Deprecation::isEnabled(); $this->oldHandler = set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) { if ($errno === E_USER_DEPRECATED) { if (str_contains($errstr, 'SilverStripe\\Dev\\Tests\\DeprecationTest')) { - throw new Deprecated($errstr, $errno, '', 1); + throw new DeprecationTestException($errstr); } else { // Suppress any E_USER_DEPRECATED unrelated to this unit-test return true; @@ -73,8 +74,8 @@ public function testNotice() 'My message.', 'Called from SilverStripe\Dev\Tests\DeprecationTest->testNotice.' ]); - $this->expectDeprecation(); - $this->expectDeprecationMessage($message); + $this->expectException(DeprecationTestException::class); + $this->expectExceptionMessage($message); Deprecation::enable(); $ret = $this->myDeprecatedMethod(); $this->assertSame('abc', $ret); @@ -90,8 +91,8 @@ public function testCallUserFunc() 'My message.', 'Called from SilverStripe\Dev\Tests\DeprecationTest->testCallUserFunc.' ]); - $this->expectDeprecation(); - $this->expectDeprecationMessage($message); + $this->expectException(DeprecationTestException::class); + $this->expectExceptionMessage($message); Deprecation::enable(); $ret = call_user_func([$this, 'myDeprecatedMethod']); $this->assertSame('abc', $ret); @@ -105,8 +106,8 @@ public function testCallUserFuncArray() 'My message.', 'Called from SilverStripe\Dev\Tests\DeprecationTest->testCallUserFuncArray.' ]); - $this->expectDeprecation(); - $this->expectDeprecationMessage($message); + $this->expectException(DeprecationTestException::class); + $this->expectExceptionMessage($message); Deprecation::enable(); $ret = call_user_func_array([$this, 'myDeprecatedMethod'], []); $this->assertSame('abc', $ret); @@ -130,8 +131,8 @@ public function testWithNoReplacementTrue() 'My message.', 'Called from SilverStripe\Dev\Tests\DeprecationTest->testWithNoReplacementTrue.' ]); - $this->expectDeprecation(); - $this->expectDeprecationMessage($message); + $this->expectException(DeprecationTestException::class); + $this->expectExceptionMessage($message); Deprecation::enable(true); $ret = Deprecation::withNoReplacement(function () { return $this->myDeprecatedMethod(); @@ -147,8 +148,8 @@ public function testWithNoReplacementTrueCallUserFunc() 'My message.', 'Called from SilverStripe\Dev\Tests\DeprecationTest->testWithNoReplacementTrueCallUserFunc.' ]); - $this->expectDeprecation(); - $this->expectDeprecationMessage($message); + $this->expectException(DeprecationTestException::class); + $this->expectExceptionMessage($message); Deprecation::enable(true); $ret = Deprecation::withNoReplacement(function () { return call_user_func([$this, 'myDeprecatedMethod']); @@ -164,8 +165,8 @@ public function testNoticeWithNoReplacementTrue() 'My message.', 'Called from PHPUnit\Framework\TestCase->runTest.' ]); - $this->expectDeprecation(); - $this->expectDeprecationMessage($message); + $this->expectException(DeprecationTestException::class); + $this->expectExceptionMessage($message); Deprecation::enable(true); Deprecation::withNoReplacement(function () { Deprecation::notice('123', 'My message.'); @@ -180,8 +181,8 @@ public function testClassWithNoReplacement() 'Some class message.', 'Called from SilverStripe\Dev\Tests\DeprecationTest->testClassWithNoReplacement.' ]); - $this->expectDeprecation(); - $this->expectDeprecationMessage($message); + $this->expectException(DeprecationTestException::class); + $this->expectExceptionMessage($message); Deprecation::enable(true); // using this syntax because my IDE was complaining about DeprecationTestObject not existing // when trying to use `new DeprecationTestObject();` @@ -197,8 +198,8 @@ public function testClassWithInjectorWithNoReplacement() 'Some class message.', 'Called from SilverStripe\Dev\Tests\DeprecationTest->testClassWithInjectorWithNoReplacement.' ]); - $this->expectDeprecation(); - $this->expectDeprecationMessage($message); + $this->expectException(DeprecationTestException::class); + $this->expectExceptionMessage($message); Deprecation::enable(true); Injector::inst()->get(DeprecationTestObject::class); Deprecation::outputNotices(); @@ -229,8 +230,8 @@ public function testConfigGetFirst() 'Config SilverStripe\Dev\Tests\DeprecationTest\DeprecationTestObject.first_config is deprecated.', 'My first config message.' ]); - $this->expectDeprecation(); - $this->expectDeprecationMessage($message); + $this->expectException(DeprecationTestException::class); + $this->expectExceptionMessage($message); Deprecation::enable(); Config::inst()->get(DeprecationTestObject::class, 'first_config'); Deprecation::outputNotices(); @@ -242,8 +243,8 @@ public function testConfigGetSecond() 'Config SilverStripe\Dev\Tests\DeprecationTest\DeprecationTestObject.second_config is deprecated.', 'My second config message.' ]); - $this->expectDeprecation(); - $this->expectDeprecationMessage($message); + $this->expectException(DeprecationTestException::class); + $this->expectExceptionMessage($message); Deprecation::enable(); Config::inst()->get(DeprecationTestObject::class, 'second_config'); Deprecation::outputNotices(); @@ -252,8 +253,8 @@ public function testConfigGetSecond() public function testConfigGetThird() { $message = 'Config SilverStripe\Dev\Tests\DeprecationTest\DeprecationTestObject.third_config is deprecated.'; - $this->expectDeprecation(); - $this->expectDeprecationMessage($message); + $this->expectException(DeprecationTestException::class); + $this->expectExceptionMessage($message); Deprecation::enable(); Config::inst()->get(DeprecationTestObject::class, 'third_config'); Deprecation::outputNotices(); @@ -265,8 +266,8 @@ public function testConfigSet() 'Config SilverStripe\Dev\Tests\DeprecationTest\DeprecationTestObject.first_config is deprecated.', 'My first config message.' ]); - $this->expectDeprecation(); - $this->expectDeprecationMessage($message); + $this->expectException(DeprecationTestException::class); + $this->expectExceptionMessage($message); Deprecation::enable(); Config::modify()->set(DeprecationTestObject::class, 'first_config', 'abc'); Deprecation::outputNotices(); @@ -278,8 +279,8 @@ public function testConfigMerge() 'Config SilverStripe\Dev\Tests\DeprecationTest\DeprecationTestObject.array_config is deprecated.', 'My array config message.' ]); - $this->expectDeprecation(); - $this->expectDeprecationMessage($message); + $this->expectException(DeprecationTestException::class); + $this->expectExceptionMessage($message); Deprecation::enable(); Config::modify()->merge(DeprecationTestObject::class, 'array_config', ['abc']); Deprecation::outputNotices(); diff --git a/tests/php/Dev/DeprecationTest/DeprecationTestException.php b/tests/php/Dev/DeprecationTest/DeprecationTestException.php new file mode 100644 index 00000000000..7d5e3e4ffa5 --- /dev/null +++ b/tests/php/Dev/DeprecationTest/DeprecationTestException.php @@ -0,0 +1,10 @@ +expectException(InvalidArgumentException::class); - $this->expectDeprecationMessage('Fans is not a linear relation on model SilverStripe\ORM\Tests\DataObjectTest\Player'); + $this->expectExceptionMessage('Fans is not a linear relation on model SilverStripe\ORM\Tests\DataObjectTest\Player'); $list = Team::get(); $list->sort('Founder.Fans.Surname'); // Can't sort on has_many } diff --git a/tests/php/ORM/DataQueryTest.php b/tests/php/ORM/DataQueryTest.php index b0cfc9103ae..ee0415ef24d 100644 --- a/tests/php/ORM/DataQueryTest.php +++ b/tests/php/ORM/DataQueryTest.php @@ -10,6 +10,7 @@ use SilverStripe\ORM\Queries\SQLSelect; use SilverStripe\ORM\Tests\DataQueryTest\ObjectE; use SilverStripe\Security\Member; +use SilverStripe\ORM\Tests\DataQueryTest\DataQueryTestException; class DataQueryTest extends SapphireTest { @@ -35,6 +36,28 @@ class DataQueryTest extends SapphireTest SQLSelectTest\TestChild::class, ]; + /** + * @param callable|null $oldHandler + */ + private $oldHandler = null; + + protected function setup(): void + { + // Use custom error handler to allow the use of expectException() to catch errors + // which is required in testFieldCollision(). PHPUnit does not support expecting errors + parent::setup(); + $this->oldHandler = set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) { + throw new DataQueryTestException($errstr); + }); + } + + protected function tearDown(): void + { + restore_error_handler(); + $this->oldHandler = null; + parent::tearDown(); + } + public function testSortByJoinedFieldRetainsSourceInformation() { $bar = new DataQueryTest\ObjectC(); @@ -235,8 +258,8 @@ public function testFieldCollision($allowCollisions) if ($allowCollisions) { $this->assertSQLContains('THEN "DataQueryTest_B"."Title" WHEN COALESCE(NULL, 1) AS "Title" IS NOT NULL THEN COALESCE(NULL, 1) AS "Title" ELSE NULL END AS "Title"', $dataQuery->sql()); } else { - $this->expectError(); - $this->expectErrorMessageMatches('/^Bad collision item /'); + $this->expectException(DataQueryTestException::class); + $this->expectExceptionMessageMatches('/^Bad collision item /'); } $dataQuery->getFinalisedQuery(); diff --git a/tests/php/ORM/DataQueryTest/DataQueryTestException.php b/tests/php/ORM/DataQueryTest/DataQueryTestException.php new file mode 100644 index 00000000000..cc15815b945 --- /dev/null +++ b/tests/php/ORM/DataQueryTest/DataQueryTestException.php @@ -0,0 +1,10 @@ +