diff --git a/composer.json b/composer.json index b25ea980d90..4e8fed3e73c 100644 --- a/composer.json +++ b/composer.json @@ -32,10 +32,10 @@ "m1/env": "^2.2.0", "masterminds/html5": "^2.7.6", "monolog/monolog": "^3.2.0", - "nikic/php-parser": "^4.15.0", + "nikic/php-parser": "^5.1.0", "psr/container": "^1.1 || ^2.0", "psr/http-message": "^1", - "sebastian/diff": "^4.0", + "sebastian/diff": "^6.0", "silverstripe/config": "^3", "silverstripe/assets": "^3", "silverstripe/vendor-plugin": "^2", @@ -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/src/Core/Manifest/ClassManifest.php b/src/Core/Manifest/ClassManifest.php index 0e2887635ab..a89a38f75f6 100644 --- a/src/Core/Manifest/ClassManifest.php +++ b/src/Core/Manifest/ClassManifest.php @@ -302,7 +302,7 @@ public function init($includeTests = false, $forceRegen = false) public function getParser() { if (!$this->parser) { - $this->parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7); + $this->parser = (new ParserFactory)->createForHostVersion(); } return $this->parser; diff --git a/src/Core/Manifest/ClassManifestErrorHandler.php b/src/Core/Manifest/ClassManifestErrorHandler.php index d077daa9388..0feb070e8c6 100644 --- a/src/Core/Manifest/ClassManifestErrorHandler.php +++ b/src/Core/Manifest/ClassManifestErrorHandler.php @@ -24,7 +24,7 @@ public function __construct($pathname) $this->pathname = $pathname; } - public function handleError(Error $error) + public function handleError(Error $error): void { $newMessage = sprintf('%s in %s', $error->getRawMessage(), $this->pathname); $error->setRawMessage($newMessage); diff --git a/src/Dev/Constraint/SSListContains.php b/src/Dev/Constraint/SSListContains.php index e9880ee22b6..c1dd4e5927b 100644 --- a/src/Dev/Constraint/SSListContains.php +++ b/src/Dev/Constraint/SSListContains.php @@ -4,7 +4,6 @@ use PHPUnit\Framework\Constraint\Constraint; use PHPUnit\Framework\ExpectationFailedException; -use SilverStripe\Dev\SSListExporter; use SilverStripe\Dev\TestOnly; use SilverStripe\ORM\SS_List; use SilverStripe\View\ViewableData; @@ -20,8 +19,6 @@ class SSListContains extends Constraint implements TestOnly */ protected $matches = []; - protected SSListExporter $exporter; - /** * Check if the list has left over items that don't match * @@ -31,8 +28,6 @@ class SSListContains extends Constraint implements TestOnly public function __construct(array $matches) { - $this->exporter = new SSListExporter(); - $this->matches = $matches; } diff --git a/src/Dev/Constraint/SSListContainsOnlyMatchingItems.php b/src/Dev/Constraint/SSListContainsOnlyMatchingItems.php index a08b20f53cb..9824cc7a85e 100644 --- a/src/Dev/Constraint/SSListContainsOnlyMatchingItems.php +++ b/src/Dev/Constraint/SSListContainsOnlyMatchingItems.php @@ -4,7 +4,6 @@ use PHPUnit\Framework\Constraint\Constraint; use PHPUnit\Framework\ExpectationFailedException; -use SilverStripe\Dev\SSListExporter; use SilverStripe\Dev\TestOnly; use SilverStripe\ORM\SS_List; @@ -19,8 +18,6 @@ class SSListContainsOnlyMatchingItems extends Constraint implements TestOnly */ private $match; - protected SSListExporter $exporter; - /** * @var ViewableDataContains */ @@ -28,8 +25,6 @@ class SSListContainsOnlyMatchingItems extends Constraint implements TestOnly public function __construct($match) { - $this->exporter = new SSListExporter(); - $this->constraint = new ViewableDataContains($match); $this->match = $match; } diff --git a/src/Dev/Exceptions/ExpectedErrorException.php b/src/Dev/Exceptions/ExpectedErrorException.php new file mode 100644 index 00000000000..0ef7ec63684 --- /dev/null +++ b/src/Dev/Exceptions/ExpectedErrorException.php @@ -0,0 +1,9 @@ +contains($value)) !== false) { - return $className . ' &' . $key; - } - - $list = $value; - $key = $processed->add($value); - $values = ''; - - if ($list->count() > 0) { - foreach ($list as $k => $v) { - $values .= sprintf( - '%s %s ' . "\n", - $whitespace, - $this->recursiveExport($v, $indentation) - ); - } - - $values = "\n" . $values . $whitespace; - } - - return sprintf($className . ' &%s (%s)', $key, $values); - } - - if ($value instanceof ViewableData) { - $className = get_class($value); - $data = $this->toMap($value); - - return sprintf( - '%s %s => %s' . "\n", - $whitespace, - $className, - $this->recursiveExport($data, $indentation + 2, $processed) - ); - } - - - return parent::recursiveExport($value, $indentation, $processed); - } - - /** - * @param ViewableData $object - * @return array - */ - public function toMap(ViewableData $object) - { - return $object->hasMethod('toMap') - ? $object->toMap() - : []; - } -} diff --git a/src/Dev/SapphireTest.php b/src/Dev/SapphireTest.php index b54a58e5554..3e37406d954 100644 --- a/src/Dev/SapphireTest.php +++ b/src/Dev/SapphireTest.php @@ -3,11 +3,13 @@ namespace SilverStripe\Dev; use Exception; +use Facebook\WebDriver\Exception\UnknownErrorException; use InvalidArgumentException; use LogicException; use PHPUnit\Framework\Constraint\LogicalNot; use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Exception as PHPUnitFrameworkException; +use PHPUnit\Framework\TestSize\Unknown; use PHPUnit\Util\Test as TestUtil; use SilverStripe\CMS\Controllers\RootURLController; use SilverStripe\Control\CLIRequestBuilder; @@ -41,6 +43,12 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Mailer\Transport\NullTransport; +use ReflectionMethod; +use ReflectionClass; +use SilverStripe\Dev\Exceptions\ExpectedErrorException; +use SilverStripe\Dev\Exceptions\ExpectedNoticeException; +use SilverStripe\Dev\Exceptions\ExpectedWarningException; +use SilverStripe\Dev\Exceptions\UnexpectedErrorException; /** * Test case class for the Silverstripe framework. @@ -334,6 +342,37 @@ protected function setUp(): void Email::config()->remove('bcc_all_emails_to'); } + /** + * @param callable|null $oldHandler + */ + private $oldErrorHandler = null; + + /** + * Setup a custom error handler to throw exceptions on errors + */ + protected function enableErrorHandler() + { + // If changing this method, ensure that the corresponding table on 00_Unit_Testing.md + // in silverstripe/deveoper-docs is also updated + $this->oldErrorHandler = set_error_handler( + function (int $errno, string $errstr, string $errfile, int $errline) { + // E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING + // cannot be handled in set_error_handler() + // https://www.php.net/manual/en/function.set-error-handler.php + // https://www.php.net/manual/en/errorfunc.constants.php + if (in_array($errno, [E_USER_ERROR, E_RECOVERABLE_ERROR])) { + throw new ExpectedErrorException($errstr); + } elseif (in_array($errno, [E_NOTICE, E_USER_NOTICE])) { + throw new ExpectedNoticeException($errstr); + } elseif (in_array($errno, [E_WARNING, E_USER_WARNING])) { + throw new ExpectedWarningException($errstr); + } + // Use the standard PHP error handler + return false; + } + ); + } + /** * Helper method to determine if the current test should enable a test database * @@ -563,6 +602,12 @@ protected function tearDown(): void // Call state helpers static::$state->tearDown($this); + + // Reset custom error handler + if ($this->oldErrorHandler) { + restore_error_handler(); + $this->oldErrorHandler = null; + } } /** @@ -1212,16 +1257,30 @@ public static function createInvalidArgumentException($argument, $type, $value = } /** - * Returns the annotations for this test. - * - * @return array + * Returns the annotations for this test */ public function getAnnotations(): array { - return TestUtil::parseTestMethodAnnotations( - get_class($this), - $this->getName(false) - ); + $class = get_class($this); + $method = $this->name(); + $ret = []; + foreach (['method', 'class'] as $what) { + if ($what === 'method') { + $reflection = new ReflectionMethod($class, $method); + } else { + $reflection = new ReflectionClass($class); + } + preg_match_all('#@(.*?)\n#s', $reflection->getDocComment(), $annotations); + $ret[$what] = []; + foreach ($annotations[1] as $annotation) { + $parts = explode(' ', $annotation); + $key = array_shift($parts); + $value = implode(' ', $parts); + $ret[$what][$key] ??= []; + $ret[$what][$key][] = $value; + } + } + return $ret; } /** diff --git a/src/ORM/FieldType/DBClassNameTrait.php b/src/ORM/FieldType/DBClassNameTrait.php index 53434f48ab8..6a892b59aaf 100644 --- a/src/ORM/FieldType/DBClassNameTrait.php +++ b/src/ORM/FieldType/DBClassNameTrait.php @@ -2,10 +2,10 @@ namespace SilverStripe\ORM\FieldType; +use RuntimeException; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Config\Config; use SilverStripe\ORM\DataObject; -use RuntimeException; use SilverStripe\View\ViewableData; trait DBClassNameTrait diff --git a/src/View/Parsers/HtmlDiff.php b/src/View/Parsers/HtmlDiff.php index 17ea1763911..10240d7b2cc 100644 --- a/src/View/Parsers/HtmlDiff.php +++ b/src/View/Parsers/HtmlDiff.php @@ -7,6 +7,7 @@ use SebastianBergmann\Diff\Differ; use SilverStripe\Core\Convert; use SilverStripe\Core\Injector\Injector; +use SebastianBergmann\Diff\Output\DiffOnlyOutputBuilder; /** * Class representing a 'diff' between two sequences of HTML strings. @@ -285,7 +286,7 @@ private static function cleanHTML(string $content, ?HTMLCleaner $cleaner = null) private static function getDiffer(): Differ { if (!HtmlDiff::$differ) { - HtmlDiff::$differ = new Differ(); + HtmlDiff::$differ = new Differ(new DiffOnlyOutputBuilder()); } return HtmlDiff::$differ; } diff --git a/tests/php/Control/ControllerTest.php b/tests/php/Control/ControllerTest.php index 29d520eb6ae..d62bf4285be 100644 --- a/tests/php/Control/ControllerTest.php +++ b/tests/php/Control/ControllerTest.php @@ -18,6 +18,7 @@ use SilverStripe\Dev\FunctionalTest; use SilverStripe\Security\Member; use SilverStripe\View\SSViewer; +use PHPUnit\Framework\Attributes\DataProvider; class ControllerTest extends FunctionalTest { @@ -462,7 +463,7 @@ public function testJoinLinks() ); } - public function provideNormaliseTrailingSlash(): array + public static function provideNormaliseTrailingSlash(): array { // note 93.184.215.14 is the IP address for example.com return [ @@ -670,9 +671,7 @@ public function provideNormaliseTrailingSlash(): array ]; } - /** - * @dataProvider provideNormaliseTrailingSlash - */ + #[DataProvider('provideNormaliseTrailingSlash')] public function testNormaliseTrailingSlash(string $path, string $withSlash, string $withoutSlash): void { $absBaseUrlNoSlash = rtrim(Director::absoluteBaseURL(), '/'); @@ -704,9 +703,6 @@ public function testLink() $this->assertEquals('HasAction/allowed-action/', $controller->Link('allowed-action')); } - /** - * @covers \SilverStripe\Control\Controller::hasAction - */ public function testHasAction() { $controller = new HasAction(); diff --git a/tests/php/Control/DirectorTest.php b/tests/php/Control/DirectorTest.php index 1c65b5bb328..5ee9c7b5ab1 100644 --- a/tests/php/Control/DirectorTest.php +++ b/tests/php/Control/DirectorTest.php @@ -17,6 +17,7 @@ use SilverStripe\Core\Environment; use SilverStripe\Core\Kernel; use SilverStripe\Dev\SapphireTest; +use PHPUnit\Framework\Attributes\DataProvider; class DirectorTest extends SapphireTest { @@ -40,7 +41,6 @@ protected function setUp(): void ->setForceSSLPatterns([]) ->setForceWWW(null) ->setEnabledEnvs(true); - $this->expectedRedirect = null; } protected function tearDown(): void @@ -214,14 +214,14 @@ public function testAlternativeBaseURL() /** * Tests that {@link Director::is_absolute()} works under different environment types - * @dataProvider provideAbsolutePaths */ + #[DataProvider('provideAbsolutePaths')] public function testIsAbsolute($path, $result) { $this->assertEquals($result, Director::is_absolute($path)); } - public function provideAbsolutePaths() + public static function provideAbsolutePaths() { return [ ['C:/something', true], @@ -294,7 +294,7 @@ public function testIsRelativeUrl() /** * @return array */ - public function providerMakeRelative() + public static function providerMakeRelative() { return [ // Resilience to slash position @@ -409,11 +409,11 @@ public function providerMakeRelative() } /** - * @dataProvider providerMakeRelative * @param string $baseURL Site base URL * @param string $requestURL Request URL * @param string $relativeURL Expected relative URL */ + #[DataProvider('providerMakeRelative')] public function testMakeRelative($baseURL, $requestURL, $relativeURL) { Director::config()->set('alternate_base_url', $baseURL); @@ -543,7 +543,7 @@ public function testResetGlobalsAfterTestRequest() ); } - public function providerTestTestRequestCarriesGlobals() + public static function providerTestTestRequestCarriesGlobals() { $tests = []; $fixture = ['somekey' => 'sometestvalue']; @@ -558,11 +558,11 @@ public function providerTestTestRequestCarriesGlobals() } /** - * @dataProvider providerTestTestRequestCarriesGlobals * @param $url * @param $fixture * @param $method */ + #[DataProvider('providerTestTestRequestCarriesGlobals')] public function testTestRequestCarriesGlobals($url, $fixture, $method) { $getresponse = Director::test( @@ -602,11 +602,12 @@ public function testRouteParams() public function testForceWWW() { - $this->expectExceptionRedirect('http://www.mysite.com:9090/some-url'); - Director::mockRequest(function ($request) { - Injector::inst()->registerService($request, HTTPRequest::class); - Director::forceWWW(); - }, 'http://mysite.com:9090/some-url'); + $this->withExpectExceptionRedirect('http://www.mysite.com:9090/some-url', function () { + Director::mockRequest(function ($request) { + Injector::inst()->registerService($request, HTTPRequest::class); + Director::forceWWW(); + }, 'http://mysite.com:9090/some-url'); + }); } public function testPromisedForceWWW() @@ -632,11 +633,12 @@ public function testPromisedForceWWW() public function testForceSSLProtectsEntireSite() { - $this->expectExceptionRedirect('https://www.mysite.com:9090/some-url'); - Director::mockRequest(function ($request) { - Injector::inst()->registerService($request, HTTPRequest::class); - Director::forceSSL(); - }, 'http://www.mysite.com:9090/some-url'); + $this->withExpectExceptionRedirect('https://www.mysite.com:9090/some-url', function () { + Director::mockRequest(function ($request) { + Injector::inst()->registerService($request, HTTPRequest::class); + Director::forceSSL(); + }, 'http://www.mysite.com:9090/some-url'); + }); } public function testPromisedForceSSL() @@ -664,21 +666,23 @@ public function testPromisedForceSSL() public function testForceSSLOnTopLevelPagePattern() { // Expect admin to trigger redirect - $this->expectExceptionRedirect('https://www.mysite.com:9090/admin'); - Director::mockRequest(function (HTTPRequest $request) { - Injector::inst()->registerService($request, HTTPRequest::class); - Director::forceSSL(['/^admin/']); - }, 'http://www.mysite.com:9090/admin'); + $this->withExpectExceptionRedirect('https://www.mysite.com:9090/admin', function () { + Director::mockRequest(function (HTTPRequest $request) { + Injector::inst()->registerService($request, HTTPRequest::class); + Director::forceSSL(['/^admin/']); + }, 'http://www.mysite.com:9090/admin'); + }); } public function testForceSSLOnSubPagesPattern() { // Expect to redirect to security login page - $this->expectExceptionRedirect('https://www.mysite.com:9090/Security/login'); - Director::mockRequest(function (HTTPRequest $request) { - Injector::inst()->registerService($request, HTTPRequest::class); - Director::forceSSL(['/^Security/']); - }, 'http://www.mysite.com:9090/Security/login'); + $this->withExpectExceptionRedirect('https://www.mysite.com:9090/Security/login', function () { + Director::mockRequest(function (HTTPRequest $request) { + Injector::inst()->registerService($request, HTTPRequest::class); + Director::forceSSL(['/^Security/']); + }, 'http://www.mysite.com:9090/Security/login'); + }); } public function testForceSSLWithPatternDoesNotMatchOtherPages() @@ -701,21 +705,23 @@ public function testForceSSLWithPatternDoesNotMatchOtherPages() public function testForceSSLAlternateDomain() { // Ensure that forceSSL throws the appropriate exception - $this->expectExceptionRedirect('https://secure.mysite.com/admin'); - Director::mockRequest(function (HTTPRequest $request) { - Injector::inst()->registerService($request, HTTPRequest::class); - return Director::forceSSL(['/^admin/'], 'secure.mysite.com'); - }, 'http://www.mysite.com:9090/admin'); + $this->withExpectExceptionRedirect('https://secure.mysite.com/admin', function () { + Director::mockRequest(function (HTTPRequest $request) { + Injector::inst()->registerService($request, HTTPRequest::class); + return Director::forceSSL(['/^admin/'], 'secure.mysite.com'); + }, 'http://www.mysite.com:9090/admin'); + }); } public function testForceSSLAlternateDomainWithPort() { // Ensure that forceSSL throws the appropriate exception - $this->expectExceptionRedirect('https://secure.mysite.com:81/admin'); - Director::mockRequest(function (HTTPRequest $request) { - Injector::inst()->registerService($request, HTTPRequest::class); - return Director::forceSSL(['/^admin/'], 'secure.mysite.com:81'); - }, 'http://www.mysite.com:9090/admin'); + $this->withExpectExceptionRedirect('https://secure.mysite.com:81/admin', function () { + Director::mockRequest(function (HTTPRequest $request) { + Injector::inst()->registerService($request, HTTPRequest::class); + return Director::forceSSL(['/^admin/'], 'secure.mysite.com:81'); + }, 'http://www.mysite.com:9090/admin'); + }); } /** @@ -744,40 +750,19 @@ public function testForceSSLandForceWWW() $this->assertEquals(301, $response->getStatusCode()); } - /** - * Set url to redirect to - * - * @var string - */ - protected $expectedRedirect = null; - /** * Expects this test to throw a HTTPResponse_Exception with the given redirect - * - * @param string $url */ - protected function expectExceptionRedirect($url) - { - $this->expectedRedirect = $url; - } - - protected function runTest() + protected function withExpectExceptionRedirect(string $expectedRedirect, callable $callback) { try { - $result = parent::runTest(); - if ($this->expectedRedirect) { - $this->fail("Expected to redirect to {$this->expectedRedirect} but no redirect found"); - } - return $result; + $callback(); + $this->fail("Expected to redirect to $expectedRedirect but no redirect found"); } catch (HTTPResponse_Exception $exception) { // Check URL - if ($this->expectedRedirect) { - $url = $exception->getResponse()->getHeader('Location'); - $this->assertEquals($this->expectedRedirect, $url, "Expected to redirect to {$this->expectedRedirect}"); - return null; - } else { - throw $exception; - } + $url = $exception->getResponse()->getHeader('Location'); + $this->assertEquals($expectedRedirect, $url, "Expected to redirect to $expectedRedirect"); + return null; } } diff --git a/tests/php/Control/Email/EmailTest.php b/tests/php/Control/Email/EmailTest.php index 699d910b63f..e05cf91a434 100644 --- a/tests/php/Control/Email/EmailTest.php +++ b/tests/php/Control/Email/EmailTest.php @@ -16,6 +16,7 @@ use Symfony\Component\Mime\Address; use Symfony\Component\Mime\Part\DataPart; use Symfony\Component\Mime\Part\AbstractPart; +use PHPUnit\Framework\Attributes\DataProvider; class EmailTest extends SapphireTest { @@ -66,30 +67,26 @@ private function getFirstAttachment(array $attachments): DataPart return $attachments[0]; } - /** - * @dataProvider provideValidEmailAddresses - */ + #[DataProvider('provideValidEmailAddresses')] public function testValidEmailAddress($email): void { $this->assertTrue(Email::is_valid_address($email)); } - /** - * @dataProvider provideInvalidEmailAddresses - */ + #[DataProvider('provideInvalidEmailAddresses')] public function testInvalidEmailAddress($email): void { $this->assertFalse(Email::is_valid_address($email)); } - public function provideValidEmailAddresses(): array + public static function provideValidEmailAddresses(): array { return [ ['test@example.com', 'test-123@sub.example.com'], ]; } - public function provideInvalidEmailAddresses(): array + public static function provideInvalidEmailAddresses(): array { return [ ['foo.bar@', '@example.com', 'foo@'], @@ -538,9 +535,7 @@ public function testGetDefaultFrom(): void $this->assertTrue(true); } - /** - * @dataProvider provideCreateAddressArray - */ + #[DataProvider('provideCreateAddressArray')] public function testCreateAddressArray(string|array $address, string $name, array $expected): void { $method = new \ReflectionMethod(Email::class, 'createAddressArray'); @@ -553,7 +548,7 @@ public function testCreateAddressArray(string|array $address, string $name, arra } } - public function provideCreateAddressArray(): array + public static function provideCreateAddressArray(): array { return [ [ diff --git a/tests/php/Control/HTTPRequestTest.php b/tests/php/Control/HTTPRequestTest.php index 93391c12c75..babcbda0094 100644 --- a/tests/php/Control/HTTPRequestTest.php +++ b/tests/php/Control/HTTPRequestTest.php @@ -7,6 +7,9 @@ use SilverStripe\Control\Middleware\TrustedProxyMiddleware; use SilverStripe\Control\Session; use SilverStripe\Dev\SapphireTest; +use SilverStripe\Control\Tests\HTTPRequestTest\HTTPRequestTestException; +use PHPUnit\Framework\Attributes\DataProvider; +use SilverStripe\Dev\Exceptions\ExpectedWarningException; class HTTPRequestTest extends SapphireTest { @@ -55,7 +58,9 @@ public function testWildCardMatch() */ public function testWildCardWithFurtherParams() { - $this->expectWarning(); + $this->enableErrorHandler(); + $this->expectException(ExpectedWarningException::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); @@ -150,7 +155,7 @@ public function detectMethodDataProvider() ]; } - public function setHttpMethodDataProvider() + public static function setHttpMethodDataProvider() { return [ 'POST request' => ['POST','POST'], @@ -162,9 +167,7 @@ public function setHttpMethodDataProvider() ]; } - /** - * @dataProvider setHttpMethodDataProvider - */ + #[DataProvider('setHttpMethodDataProvider')] public function testSetHttpMethod($method, $expected) { $request = new HTTPRequest('GET', '/hello'); diff --git a/tests/php/Control/HTTPResponseTest.php b/tests/php/Control/HTTPResponseTest.php index 88c1aaeeba8..04b6ad32249 100644 --- a/tests/php/Control/HTTPResponseTest.php +++ b/tests/php/Control/HTTPResponseTest.php @@ -5,6 +5,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\Control\HTTPResponse; use SilverStripe\Control\HTTPResponse_Exception; +use PHPUnit\Framework\Attributes\DataProvider; class HTTPResponseTest extends SapphireTest { @@ -45,7 +46,7 @@ public function testRemoveHeader() $this->assertEmpty($response->getHeader('X-Animal')); } - public function providerSanitiseHeaders() + public static function providerSanitiseHeaders() { return [ 'plain text is retained' => ['some arbitrary value1', 'some arbitrary value1'], @@ -54,9 +55,7 @@ public function providerSanitiseHeaders() ]; } - /** - * @dataProvider providerSanitiseHeaders - */ + #[DataProvider('providerSanitiseHeaders')] public function testSanitiseHeaders(string $expected, string $value) { $response = new HTTPResponse(); @@ -65,7 +64,7 @@ public function testSanitiseHeaders(string $expected, string $value) $this->assertSame($expected, $response->getHeader('X-Sanitised')); } - public function providerTestValidStatusCodes() + public static function providerTestValidStatusCodes() { return [ [200, 'OK'], @@ -76,10 +75,10 @@ public function providerTestValidStatusCodes() } /** - * @dataProvider providerTestValidStatusCodes * @param int $code * @param string $status */ + #[DataProvider('providerTestValidStatusCodes')] public function testValidStatusCodes($code, $status) { $response = new HTTPResponse(); diff --git a/tests/php/Control/HttpRequestMockBuilder.php b/tests/php/Control/HttpRequestMockBuilder.php index ffbd2cbfcfe..ef06255e580 100644 --- a/tests/php/Control/HttpRequestMockBuilder.php +++ b/tests/php/Control/HttpRequestMockBuilder.php @@ -28,19 +28,19 @@ public function buildRequestMock($url, $getVars = [], $postVars = [], $method = $request->method('getSession')->willReturn($session); - $request->method('getURL')->will($this->returnCallback(static function ($addParams) use ($url, $getVars) { + $request->method('getURL')->willReturnCallback(static function ($addParams) use ($url, $getVars) { return $addParams && count($getVars ?? []) ? $url . '?' . http_build_query($getVars) : $url; - })); + }); $request->method('getVars')->willReturn($getVars); - $request->method('getVar')->will($this->returnCallback(static function ($key) use ($getVars) { + $request->method('getVar')->willReturnCallback(static function ($key) use ($getVars) { return isset($getVars[$key]) ? $getVars[$key] : null; - })); + }); $request->method('postVars')->willReturn($postVars); - $request->method('postVar')->will($this->returnCallback(static function ($key) use ($postVars) { + $request->method('postVar')->willReturnCallback(static function ($key) use ($postVars) { return isset($postVars[$key]) ? $postVars[$key] : null; - })); + }); if (is_null($method)) { if (count($postVars ?? [])) { diff --git a/tests/php/Control/Middleware/CanonicalURLMiddlewareTest.php b/tests/php/Control/Middleware/CanonicalURLMiddlewareTest.php index e68af11bae5..450b8d1ca0e 100644 --- a/tests/php/Control/Middleware/CanonicalURLMiddlewareTest.php +++ b/tests/php/Control/Middleware/CanonicalURLMiddlewareTest.php @@ -9,6 +9,7 @@ use SilverStripe\Core\Environment; use SilverStripe\Dev\SapphireTest; use SilverStripe\Control\Director; +use PHPUnit\Framework\Attributes\DataProvider; class CanonicalURLMiddlewareTest extends SapphireTest { @@ -86,7 +87,7 @@ public function testGetForceBasicAuthToSSL() $this->assertFalse($middleware->getForceBasicAuthToSSL(), 'Explicitly set is returned'); } - public function provideRedirectTrailingSlash() + public static function provideRedirectTrailingSlash() { $testScenarios = []; foreach ([true, false] as $forceRedirect) { @@ -103,9 +104,7 @@ public function provideRedirectTrailingSlash() return $testScenarios; } - /** - * @dataProvider provideRedirectTrailingSlash - */ + #[DataProvider('provideRedirectTrailingSlash')] public function testRedirectTrailingSlash(bool $forceRedirect, bool $addTrailingSlash, bool $requestHasSlash) { Controller::config()->set('add_trailing_slash', $addTrailingSlash); @@ -147,7 +146,7 @@ private function performRedirectTest(string $requestURL, CanonicalURLMiddleware } } - public function provideRedirectTrailingSlashIgnorePaths() + public static function provideRedirectTrailingSlashIgnorePaths() { return [ [ @@ -169,9 +168,7 @@ public function provideRedirectTrailingSlashIgnorePaths() ]; } - /** - * @dataProvider provideRedirectTrailingSlashIgnorePaths - */ + #[DataProvider('provideRedirectTrailingSlashIgnorePaths')] public function testRedirectTrailingSlashIgnorePaths(bool $addTrailingSlash, bool $requestHasSlash) { Controller::config()->set('add_trailing_slash', $addTrailingSlash); @@ -206,7 +203,7 @@ private function getMockedMiddleware($mockGetRedirect = true): CanonicalURLMiddl /** @var CanonicalURLMiddleware $middleware */ $middleware = $this->getMockBuilder(CanonicalURLMiddleware::class) - ->setMethods($mockedMethods) + ->onlyMethods($mockedMethods) ->getMock(); $middleware->expects($this->any())->method('isEnabled')->willReturn(true); diff --git a/tests/php/Control/Middleware/HTTPCacheControlMiddlewareTest.php b/tests/php/Control/Middleware/HTTPCacheControlMiddlewareTest.php index bd9adbfc920..d559b589286 100644 --- a/tests/php/Control/Middleware/HTTPCacheControlMiddlewareTest.php +++ b/tests/php/Control/Middleware/HTTPCacheControlMiddlewareTest.php @@ -5,6 +5,7 @@ use SilverStripe\Control\HTTPResponse; use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware; use SilverStripe\Dev\SapphireTest; +use PHPUnit\Framework\Attributes\DataProvider; class HTTPCacheControlMiddlewareTest extends SapphireTest { @@ -18,7 +19,7 @@ protected function setUp(): void HTTPCacheControlMiddleware::reset(); } - public function provideCacheStates() + public static function provideCacheStates() { return [ ['enableCache', false], @@ -28,9 +29,7 @@ public function provideCacheStates() ]; } - /** - * @dataProvider provideCacheStates - */ + #[DataProvider('provideCacheStates')] public function testCheckDefaultStates($state, $immutable) { $cc = HTTPCacheControlMiddleware::singleton(); @@ -42,9 +41,7 @@ public function testCheckDefaultStates($state, $immutable) $this->assertStringContainsString('must-revalidate', $response->getHeader('cache-control')); } - /** - * @dataProvider provideCacheStates - */ + #[DataProvider('provideCacheStates')] public function testSetMaxAge($state, $immutable) { $cc = HTTPCacheControlMiddleware::singleton(); @@ -127,9 +124,7 @@ public function testPublicCacheWithMaxAgeAppliesWhenLevelDoesNot() $this->assertStringContainsString('max-age=300', $response->getHeader('cache-control')); } - /** - * @dataProvider provideCacheStates - */ + #[DataProvider('provideCacheStates')] public function testSetNoStore($state, $immutable) { $cc = HTTPCacheControlMiddleware::singleton(); @@ -156,9 +151,7 @@ public function testSetNoStore($state, $immutable) } } - /** - * @dataProvider provideCacheStates - */ + #[DataProvider('provideCacheStates')] public function testSetNoCache($state, $immutable) { $cc = HTTPCacheControlMiddleware::singleton(); @@ -185,9 +178,7 @@ public function testSetNoCache($state, $immutable) } } - /** - * @dataProvider provideCacheStates - */ + #[DataProvider('provideCacheStates')] public function testSetSharedMaxAge($state, $immutable) { $cc = HTTPCacheControlMiddleware::singleton(); @@ -212,9 +203,7 @@ public function testSetSharedMaxAge($state, $immutable) } } - /** - * @dataProvider provideCacheStates - */ + #[DataProvider('provideCacheStates')] public function testSetMustRevalidate($state, $immutable) { $cc = HTTPCacheControlMiddleware::singleton(); diff --git a/tests/php/Control/PjaxResponseNegotiatorTest.php b/tests/php/Control/PjaxResponseNegotiatorTest.php index e1c2d5f06e6..cded49d91ce 100644 --- a/tests/php/Control/PjaxResponseNegotiatorTest.php +++ b/tests/php/Control/PjaxResponseNegotiatorTest.php @@ -65,9 +65,9 @@ public function testMultipleFragments() $request->addHeader('Accept', 'application/json'); $response = $negotiator->respond($request); $json = json_decode($response->getBody() ?? ''); - $this->assertObjectHasAttribute('myfragment', $json); + $this->assertObjectHasProperty('myfragment', $json); $this->assertEquals('myfragment response', $json->myfragment); - $this->assertObjectHasAttribute('otherfragment', $json); + $this->assertObjectHasProperty('otherfragment', $json); $this->assertEquals('otherfragment response', $json->otherfragment); } @@ -92,6 +92,6 @@ public function testFragmentsOverride() $response = $negotiator->setFragmentOverride(['beta'])->respond($request); $json = json_decode($response->getBody() ?? ''); $this->assertFalse(isset($json->alpha)); - $this->assertObjectHasAttribute('beta', $json); + $this->assertObjectHasProperty('beta', $json); } } diff --git a/tests/php/Control/RequestHandlerTest.php b/tests/php/Control/RequestHandlerTest.php index 98d02406048..bdbbbd04da3 100644 --- a/tests/php/Control/RequestHandlerTest.php +++ b/tests/php/Control/RequestHandlerTest.php @@ -5,7 +5,10 @@ use SilverStripe\Control\Controller; use SilverStripe\Control\Director; use SilverStripe\Control\RequestHandler; +use SilverStripe\Control\Tests\RequestHandlerTest\RequestHandlerTestException; use SilverStripe\Dev\SapphireTest; +use PHPUnit\Framework\Attributes\DataProvider; +use SilverStripe\Dev\Exceptions\ExpectedWarningException; /** * Tests for the RequestHandler class @@ -14,7 +17,7 @@ class RequestHandlerTest extends SapphireTest { protected $usesDatabase = false; - public function provideTestLink(): array + public static function provideTestLink(): array { return [ // If there's no url segment, there's no link @@ -42,14 +45,13 @@ public function provideTestLink(): array ]; } - /** - * @dataProvider provideTestLink - */ + #[DataProvider('provideTestLink')] public function testLink(?string $urlSegment, ?string $action, ?string $expected) { + $this->enableErrorHandler(); 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(ExpectedWarningException::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(); @@ -67,14 +69,13 @@ public function testLink(?string $urlSegment, ?string $action, ?string $expected $this->assertEquals($expected, $handler->Link($action)); } - /** - * @dataProvider provideTestLink - */ + #[DataProvider('provideTestLink')] public function testAbsoluteLink(?string $urlSegment, ?string $action, ?string $expected) { + $this->enableErrorHandler(); 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(ExpectedWarningException::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/SessionTest.php b/tests/php/Control/SessionTest.php index 3cae007145f..6e7aab2a288 100644 --- a/tests/php/Control/SessionTest.php +++ b/tests/php/Control/SessionTest.php @@ -15,6 +15,8 @@ use SilverStripe\Control\NullHTTPRequest; use SilverStripe\Core\Config\Config; use SilverStripe\Core\Injector\Injector; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\RunInSeparateProcess; /** * Tests to cover the {@link Session} class @@ -32,10 +34,8 @@ protected function setUp(): void parent::setUp(); } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ + #[RunInSeparateProcess] + #[PreserveGlobalState(false)] public function testInitDoesNotStartSessionWithoutIdentifier() { $req = new HTTPRequest('GET', '/'); @@ -44,10 +44,8 @@ public function testInitDoesNotStartSessionWithoutIdentifier() $this->assertFalse($session->isStarted()); } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ + #[RunInSeparateProcess] + #[PreserveGlobalState(false)] public function testInitStartsSessionWithIdentifier() { $req = new HTTPRequest('GET', '/'); @@ -57,10 +55,8 @@ public function testInitStartsSessionWithIdentifier() $this->assertTrue($session->isStarted()); } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ + #[RunInSeparateProcess] + #[PreserveGlobalState(false)] public function testInitStartsSessionWithData() { $req = new HTTPRequest('GET', '/'); @@ -69,10 +65,8 @@ public function testInitStartsSessionWithData() $this->assertTrue($session->isStarted()); } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ + #[RunInSeparateProcess] + #[PreserveGlobalState(false)] public function testStartUsesDefaultCookieNameWithHttp() { $req = (new HTTPRequest('GET', '/')) @@ -83,10 +77,8 @@ public function testStartUsesDefaultCookieNameWithHttp() $this->assertNotEquals(session_name(), $session->config()->get('cookie_name_secure')); } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ + #[RunInSeparateProcess] + #[PreserveGlobalState(false)] public function testStartUsesDefaultCookieNameWithHttpsAndCookieSecureOff() { $req = (new HTTPRequest('GET', '/')) @@ -97,10 +89,8 @@ public function testStartUsesDefaultCookieNameWithHttpsAndCookieSecureOff() $this->assertNotEquals(session_name(), $session->config()->get('cookie_name_secure')); } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ + #[RunInSeparateProcess] + #[PreserveGlobalState(false)] public function testStartUsesSecureCookieNameWithHttpsAndCookieSecureOn() { $req = (new HTTPRequest('GET', '/')) @@ -112,10 +102,8 @@ public function testStartUsesSecureCookieNameWithHttpsAndCookieSecureOn() $this->assertEquals(session_name(), $session->config()->get('cookie_name_secure')); } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ + #[RunInSeparateProcess] + #[PreserveGlobalState(false)] public function testStartErrorsWhenStartingTwice() { $this->expectException(\BadMethodCallException::class); @@ -126,10 +114,8 @@ public function testStartErrorsWhenStartingTwice() $session->start($req); } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ + #[RunInSeparateProcess] + #[PreserveGlobalState(false)] public function testStartRetainsInMemoryData() { $this->markTestIncomplete('Test'); @@ -434,7 +420,7 @@ public function testBuildCookieParams(): void ); } - public function provideSecureSamesiteData(): array + public static function provideSecureSamesiteData(): array { $data = []; foreach ([true, false] as $secure) { @@ -462,9 +448,7 @@ public function provideSecureSamesiteData(): array return $data; } - /** - * @dataProvider provideSecureSamesiteData - */ + #[DataProvider('provideSecureSamesiteData')] public function testBuildCookieParamsSecureAndSamesite( bool $secure, string $sameSite, diff --git a/tests/php/Core/Cache/DefaultCacheFactoryTest.php b/tests/php/Core/Cache/DefaultCacheFactoryTest.php index 9041f4a3ed0..ac51cfa4517 100644 --- a/tests/php/Core/Cache/DefaultCacheFactoryTest.php +++ b/tests/php/Core/Cache/DefaultCacheFactoryTest.php @@ -19,10 +19,11 @@ use Symfony\Component\Cache\Adapter\MemcachedAdapter; use Symfony\Component\Cache\Adapter\PhpFilesAdapter; use Symfony\Component\Cache\Adapter\RedisAdapter; +use PHPUnit\Framework\Attributes\DataProvider; class DefaultCacheFactoryTest extends SapphireTest { - public function provideCreate(): array + public static function provideCreate(): array { $scenarios = [ [ @@ -73,9 +74,7 @@ class_exists(Relay::class) || return $allScenarios; } - /** - * @dataProvider provideCreate - */ + #[DataProvider('provideCreate')] public function testCreate(array $args, ?string $inMemoryCacheFactory): void { $oldFactoryValue = Environment::getEnv('SS_IN_MEMORY_CACHE_FACTORY'); diff --git a/tests/php/Core/ClassInfoTest.php b/tests/php/Core/ClassInfoTest.php index 7528c3f3661..97baf8f0bc1 100644 --- a/tests/php/Core/ClassInfoTest.php +++ b/tests/php/Core/ClassInfoTest.php @@ -10,7 +10,7 @@ use SilverStripe\Core\Tests\ClassInfoTest\BaseDataClass; use SilverStripe\Core\Tests\ClassInfoTest\BaseObject; use SilverStripe\Core\Tests\ClassInfoTest\ChildClass; -use SilverStripe\Core\Tests\ClassInfoTest\ExtendTest; +use SilverStripe\Core\Tests\ClassInfoTest\ExtendTest1; use SilverStripe\Core\Tests\ClassInfoTest\ExtendTest2; use SilverStripe\Core\Tests\ClassInfoTest\ExtendTest3; use SilverStripe\Core\Tests\ClassInfoTest\ExtensionTest1; @@ -24,6 +24,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\DataObject; use SilverStripe\View\ViewableData; +use PHPUnit\Framework\Attributes\DataProvider; class ClassInfoTest extends SapphireTest { @@ -38,7 +39,7 @@ class ClassInfoTest extends SapphireTest WithCustomTable::class, WithRelation::class, BaseObject::class, - ExtendTest::class, + ExtendTest1::class, ExtendTest2::class, ExtendTest3::class, ]; @@ -145,9 +146,6 @@ public function testClassesForFolder() ); } - /** - * @covers \SilverStripe\Core\ClassInfo::ancestry() - */ public function testAncestry() { $ancestry = ClassInfo::ancestry(ChildClass::class); @@ -176,9 +174,6 @@ public function testAncestry() ); } - /** - * @covers \SilverStripe\Core\ClassInfo::dataClassesFor() - */ public function testDataClassesFor() { $expect = [ @@ -211,13 +206,10 @@ public function testDataClassesFor() $this->assertEquals($expect, ClassInfo::dataClassesFor(strtolower($classes[2] ?? ''))); } - /** - * @covers \SilverStripe\Core\ClassInfo::classesWithExtension() - */ public function testClassesWithExtensionUsingConfiguredExtensions() { $expect = [ - 'silverstripe\\core\\tests\\classinfotest\\extendtest' => ExtendTest::class, + 'silverstripe\\core\\tests\\classinfotest\\extendtest1' => ExtendTest1::class, 'silverstripe\\core\\tests\\classinfotest\\extendtest2' => ExtendTest2::class, 'silverstripe\\core\\tests\\classinfotest\\extendtest3' => ExtendTest3::class, ]; @@ -228,20 +220,17 @@ public function testClassesWithExtensionUsingConfiguredExtensions() ); $expect = [ - 'silverstripe\\core\\tests\\classinfotest\\extendtest' => ExtendTest::class, + 'silverstripe\\core\\tests\\classinfotest\\extendtest1' => ExtendTest1::class, 'silverstripe\\core\\tests\\classinfotest\\extendtest2' => ExtendTest2::class, 'silverstripe\\core\\tests\\classinfotest\\extendtest3' => ExtendTest3::class, ]; $this->assertEquals( $expect, - ClassInfo::classesWithExtension(ExtensionTest1::class, ExtendTest::class, true), + ClassInfo::classesWithExtension(ExtensionTest1::class, ExtendTest1::class, true), 'ClassInfo::testClassesWithExtension() returns class with extensions applied via class config, including the base class' ); } - /** - * @covers \SilverStripe\Core\ClassInfo::classesWithExtension() - */ public function testClassesWithExtensionUsingDynamicallyAddedExtensions() { $this->assertEquals( @@ -250,7 +239,7 @@ public function testClassesWithExtensionUsingDynamicallyAddedExtensions() 'ClassInfo::testClassesWithExtension() returns no classes for extension that hasn\'t been applied yet.' ); - ExtendTest::add_extension(ExtensionTest2::class); + ExtendTest1::add_extension(ExtensionTest2::class); $expect = [ 'silverstripe\\core\\tests\\classinfotest\\extendtest2' => ExtendTest2::class, @@ -258,17 +247,14 @@ public function testClassesWithExtensionUsingDynamicallyAddedExtensions() ]; $this->assertEquals( $expect, - ClassInfo::classesWithExtension(ExtensionTest2::class, ExtendTest::class), + ClassInfo::classesWithExtension(ExtensionTest2::class, ExtendTest1::class), 'ClassInfo::testClassesWithExtension() returns class with extra extension dynamically added' ); } - /** - * @covers \SilverStripe\Core\ClassInfo::classesWithExtension() - */ public function testClassesWithExtensionWithDynamicallyRemovedExtensions() { - ExtendTest::remove_extension(ExtensionTest1::class); + ExtendTest1::remove_extension(ExtensionTest1::class); $this->assertEquals( [], @@ -277,7 +263,7 @@ public function testClassesWithExtensionWithDynamicallyRemovedExtensions() ); } - /** @dataProvider provideHasMethodCases */ + #[DataProvider('provideHasMethodCases')] public function testHasMethod($object, $method, $output) { $this->assertEquals( @@ -286,7 +272,7 @@ public function testHasMethod($object, $method, $output) ); } - public function provideHasMethodCases() + public static function provideHasMethodCases() { return [ 'Basic object' => [ @@ -327,7 +313,7 @@ public function provideHasMethodCases() ]; } - /** @dataProvider provideClassSpecCases */ + #[DataProvider('provideClassSpecCases')] public function testParseClassSpec($input, $output) { $this->assertEquals( @@ -336,7 +322,7 @@ public function testParseClassSpec($input, $output) ); } - public function provideClassSpecCases() + public static function provideClassSpecCases() { return [ 'Standard class' => [ diff --git a/tests/php/Core/ClassInfoTest/ExtendTest.php b/tests/php/Core/ClassInfoTest/ExtendTest1.php similarity index 78% rename from tests/php/Core/ClassInfoTest/ExtendTest.php rename to tests/php/Core/ClassInfoTest/ExtendTest1.php index b03a5aa3671..8a190fae225 100644 --- a/tests/php/Core/ClassInfoTest/ExtendTest.php +++ b/tests/php/Core/ClassInfoTest/ExtendTest1.php @@ -2,7 +2,7 @@ namespace SilverStripe\Core\Tests\ClassInfoTest; -class ExtendTest extends BaseObject +class ExtendTest1 extends BaseObject { private static $extensions = [ ExtensionTest1::class, diff --git a/tests/php/Core/ClassInfoTest/ExtendTest2.php b/tests/php/Core/ClassInfoTest/ExtendTest2.php index d75ae9e2229..b18d7703e3b 100644 --- a/tests/php/Core/ClassInfoTest/ExtendTest2.php +++ b/tests/php/Core/ClassInfoTest/ExtendTest2.php @@ -2,6 +2,6 @@ namespace SilverStripe\Core\Tests\ClassInfoTest; -class ExtendTest2 extends ExtendTest +class ExtendTest2 extends ExtendTest1 { } diff --git a/tests/php/Core/ConvertTest.php b/tests/php/Core/ConvertTest.php index 0eef687a550..fc497f6edb7 100644 --- a/tests/php/Core/ConvertTest.php +++ b/tests/php/Core/ConvertTest.php @@ -8,6 +8,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\View\Parsers\URLSegmentFilter; use stdClass; +use PHPUnit\Framework\Attributes\DataProvider; /** * Test various functions on the {@link Convert} class. @@ -416,8 +417,8 @@ public function testUpperCamelToLowerCamel() * * @param string $memString * @param int $expected - * @dataProvider memString2BytesProvider */ + #[DataProvider('memString2BytesProvider')] public function testMemString2Bytes($memString, $expected) { $this->assertSame($expected, Convert::memstring2bytes($memString)); @@ -426,7 +427,7 @@ public function testMemString2Bytes($memString, $expected) /** * @return array */ - public function memString2BytesProvider() + public static function memString2BytesProvider() { return [ 'infinite' => ['-1', -1], @@ -449,8 +450,8 @@ public function memString2BytesProvider() * * @param string $bytes * @param int $expected - * @dataProvider bytes2MemStringProvider */ + #[DataProvider('bytes2MemStringProvider')] public function testBytes2MemString($bytes, $expected) { $this->assertSame($expected, Convert::bytes2memstring($bytes)); @@ -459,7 +460,7 @@ public function testBytes2MemString($bytes, $expected) /** * @return array */ - public function bytes2MemStringProvider() + public static function bytes2MemStringProvider() { return [ [0, '0B'], @@ -472,7 +473,7 @@ public function bytes2MemStringProvider() ]; } - public function providerTestSlashes() + public static function providerTestSlashes() { return [ ['bob/bob', '/', true, 'bob/bob'], @@ -497,12 +498,12 @@ public function providerTestSlashes() } /** - * @dataProvider providerTestSlashes * @param string $path * @param string $separator * @param bool $multiple * @param string $expected */ + #[DataProvider('providerTestSlashes')] public function testSlashes($path, $separator, $multiple, $expected) { $this->assertEquals($expected, Convert::slashes($path, $separator, $multiple)); diff --git a/tests/php/Core/EnvironmentTest.php b/tests/php/Core/EnvironmentTest.php index 4a454ec6088..46f6e13c960 100644 --- a/tests/php/Core/EnvironmentTest.php +++ b/tests/php/Core/EnvironmentTest.php @@ -5,10 +5,11 @@ use ReflectionClass; use SilverStripe\Core\Environment; use SilverStripe\Dev\SapphireTest; +use PHPUnit\Framework\Attributes\DataProvider; class EnvironmentTest extends SapphireTest { - public function providerTestPutEnv() + public static function providerTestPutEnv() { return [ ['_ENVTEST_BOOL=true', '_ENVTEST_BOOL', true], @@ -20,18 +21,14 @@ public function providerTestPutEnv() ]; } - /** - * @dataProvider providerTestPutenv - */ + #[DataProvider('providerTestPutenv')] public function testPutEnv($put, $var, $value) { Environment::putEnv($put); $this->assertEquals($value, Environment::getEnv($var)); } - /** - * @dataProvider providerTestPutEnv - */ + #[DataProvider('providerTestPutEnv')] public function testSetEnv($put, $var, $value) { Environment::setEnv($var, $value); @@ -68,7 +65,7 @@ public function testGetVariables() $this->assertEquals('global', $GLOBALS['test']); } - public function provideHasEnv() + public static function provideHasEnv() { $setAsOptions = [ '.env', @@ -110,9 +107,7 @@ public function provideHasEnv() return $scenarios; } - /** - * @dataProvider provideHasEnv - */ + #[DataProvider('provideHasEnv')] public function testHasEnv(?string $setAs, $value, bool $expected) { $name = '_ENVTEST_HAS_ENV'; diff --git a/tests/php/Core/Injector/InjectorTest.php b/tests/php/Core/Injector/InjectorTest.php index cb7f7b24173..101c0341bdb 100644 --- a/tests/php/Core/Injector/InjectorTest.php +++ b/tests/php/Core/Injector/InjectorTest.php @@ -27,6 +27,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\Dev\TestOnly; use stdClass; +use PHPUnit\Framework\Attributes\DataProvider; define('TEST_SERVICES', __DIR__ . '/AopProxyServiceTest'); @@ -829,9 +830,7 @@ public function testConvertServicePropertyOnCreate() $this->assertInstanceOf(OtherTestObject::class, $item->property->property); } - /** - * @dataProvider provideConvertServicePropertyBackTicks - */ + #[DataProvider('provideConvertServicePropertyBackTicks')] public function testConvertServicePropertyBackTicks($value, $expected) { Environment::setEnv('INJECTOR_TEST_CSP_A', 'ABC'); @@ -841,7 +840,7 @@ public function testConvertServicePropertyBackTicks($value, $expected) $this->assertSame($expected, $actual); } - public function provideConvertServicePropertyBackTicks() + public static function provideConvertServicePropertyBackTicks() { return [ ['`INJECTOR_TEST_CSP_A`', 'ABC'], @@ -906,12 +905,10 @@ public function testCustomFactory() ->expects($this->once()) ->method('create') ->with($this->equalTo('service'), $this->equalTo([1, 2, 3])) - ->will( - $this->returnCallback( - function ($args) { - return new InjectorTest\TestObject(); - } - ) + ->willReturnCallback( + function ($args) { + return new InjectorTest\TestObject(); + } ); $injector->registerService($factory, 'factory'); diff --git a/tests/php/Core/Manifest/ClassManifestTest.php b/tests/php/Core/Manifest/ClassManifestTest.php index fa895316e45..10113f041a8 100644 --- a/tests/php/Core/Manifest/ClassManifestTest.php +++ b/tests/php/Core/Manifest/ClassManifestTest.php @@ -5,6 +5,7 @@ use Exception; use SilverStripe\Core\Manifest\ClassManifest; use SilverStripe\Dev\SapphireTest; +use PHPUnit\Framework\Attributes\DataProvider; /** * Tests for the {@link ClassManifest} class. @@ -41,7 +42,7 @@ protected function setUp(): void /** * @return array */ - public function providerTestGetItemPath() + public static function providerTestGetItemPath() { $paths = [ ['CLASSA', 'module/classes/ClassA.php'], @@ -66,10 +67,10 @@ public function providerTestGetItemPath() } /** - * @dataProvider providerTestGetItemPath * @param string $name * @param string $path */ + #[DataProvider('providerTestGetItemPath')] public function testGetItemPath($name, $path) { $this->assertEquals("{$this->base}/$path", $this->manifest->getItemPath($name)); diff --git a/tests/php/Core/Manifest/ManifestFileFinderTest.php b/tests/php/Core/Manifest/ManifestFileFinderTest.php index 54d88b16c20..680792860a8 100644 --- a/tests/php/Core/Manifest/ManifestFileFinderTest.php +++ b/tests/php/Core/Manifest/ManifestFileFinderTest.php @@ -12,10 +12,10 @@ class ManifestFileFinderTest extends SapphireTest { protected $defaultBase; - public function __construct() + public function __construct(string $name) { $this->defaultBase = __DIR__ . '/fixtures/manifestfilefinder'; - parent::__construct(); + parent::__construct($name); } /** diff --git a/tests/php/Core/Manifest/ModuleManifestTest.php b/tests/php/Core/Manifest/ModuleManifestTest.php index 1aaac7c2b8d..89d1e75f54c 100644 --- a/tests/php/Core/Manifest/ModuleManifestTest.php +++ b/tests/php/Core/Manifest/ModuleManifestTest.php @@ -5,6 +5,7 @@ use SilverStripe\Core\Manifest\ModuleLoader; use SilverStripe\Core\Manifest\ModuleManifest; use SilverStripe\Dev\SapphireTest; +use PHPUnit\Framework\Attributes\DataProvider; class ModuleManifestTest extends SapphireTest { @@ -111,7 +112,7 @@ public function testGetResourcePathOnRoot() /** * @return array */ - public function providerTestGetModuleByPath() + public static function providerTestGetModuleByPath() { return [ ['vendor/silverstripe/modulec/code/VendorClassA.php', 'silverstripe/modulec'], @@ -120,10 +121,10 @@ public function providerTestGetModuleByPath() } /** - * @dataProvider providerTestGetModuleByPath * @param string $path * @param string $expectedModuleName */ + #[DataProvider('providerTestGetModuleByPath')] public function testGetModuleByPath($path, $expectedModuleName) { // important - load the manifest that we are working with to the ModuleLoader diff --git a/tests/php/Core/Manifest/ThemeResourceLoaderTest.php b/tests/php/Core/Manifest/ThemeResourceLoaderTest.php index 0c4c424f710..90f7fc61489 100644 --- a/tests/php/Core/Manifest/ThemeResourceLoaderTest.php +++ b/tests/php/Core/Manifest/ThemeResourceLoaderTest.php @@ -9,6 +9,7 @@ use SilverStripe\View\ThemeManifest; use SilverStripe\Dev\SapphireTest; use SilverStripe\Core\Manifest\ModuleManifest; +use PHPUnit\Framework\Attributes\DataProvider; /** * Tests for the {@link TemplateLoader} class. @@ -316,7 +317,7 @@ protected function removeTestTemplates($templates) } } - public function providerTestGetPath() + public static function providerTestGetPath() { return [ // Legacy theme @@ -372,10 +373,10 @@ public function providerTestGetPath() } /** - * @dataProvider providerTestGetPath * @param string $name Theme identifier * @param string $path Path to theme */ + #[DataProvider('providerTestGetPath')] public function testGetPath($name, $path) { $this->assertEquals($path, $this->loader->getPath($name)); diff --git a/tests/php/Core/ObjectTest.php b/tests/php/Core/ObjectTest.php index 32dfaa2fd8e..184cd65ed95 100644 --- a/tests/php/Core/ObjectTest.php +++ b/tests/php/Core/ObjectTest.php @@ -12,8 +12,8 @@ use SilverStripe\Core\Tests\ObjectTest\ExtendTest3; use SilverStripe\Core\Tests\ObjectTest\ExtendTest4; use SilverStripe\Core\Tests\ObjectTest\ExtendTest5; -use SilverStripe\Core\Tests\ObjectTest\ExtensionRemoveTest; -use SilverStripe\Core\Tests\ObjectTest\ExtensionTest; +use SilverStripe\Core\Tests\ObjectTest\ExtensionRemoveTest1; +use SilverStripe\Core\Tests\ObjectTest\ExtensionTest1; use SilverStripe\Core\Tests\ObjectTest\ExtensionTest2; use SilverStripe\Core\Tests\ObjectTest\ExtensionTest3; use SilverStripe\Core\Tests\ObjectTest\MyObject; @@ -36,7 +36,7 @@ protected function setUp(): void public function testHasmethodBehaviour() { - $obj = new ObjectTest\ExtendTest(); + $obj = new ObjectTest\ExtendTestBase(); $this->assertTrue($obj->hasMethod('extendableMethod'), "Extension method found in original spelling"); $this->assertTrue($obj->hasMethod('ExTendableMethod'), "Extension method found case-insensitive"); @@ -107,13 +107,13 @@ public function testSingletonCreation() */ public function testCreateWithArgs() { - $createdObj = ObjectTest\CreateTest::create('arg1', 'arg2', [], null, 'arg5'); + $createdObj = ObjectTest\CreateTest1::create('arg1', 'arg2', [], null, 'arg5'); $this->assertEquals($createdObj->constructArguments, ['arg1', 'arg2', [], null, 'arg5']); } public function testCreateLateStaticBinding() { - $createdObj = ObjectTest\CreateTest::create('arg1', 'arg2', [], null, 'arg5'); + $createdObj = ObjectTest\CreateTest1::create('arg1', 'arg2', [], null, 'arg5'); $this->assertEquals($createdObj->constructArguments, ['arg1', 'arg2', [], null, 'arg5']); } @@ -135,16 +135,16 @@ public function testGetExtensions() 'SilverStripe\\Core\\Tests\\oBjEcTTEST\\EXTENDTest1', "SilverStripe\\Core\\Tests\\ObjectTest\\ExtendTest2", ], - ExtensionTest::get_extensions() + ExtensionTest1::get_extensions() ); $this->assertEquals( [ 'SilverStripe\\Core\\Tests\\oBjEcTTEST\\EXTENDTest1', "SilverStripe\\Core\\Tests\\ObjectTest\\ExtendTest2('FOO', 'BAR')", ], - ExtensionTest::get_extensions(null, true) + ExtensionTest1::get_extensions(null, true) ); - $inst = new ExtensionTest(); + $inst = new ExtensionTest1(); $extensions = $inst->getExtensionInstances(); $this->assertCount(2, $extensions); $this->assertArrayHasKey(ExtendTest1::class, $extensions); @@ -174,45 +174,45 @@ public function testHasAndAddExtension() { // ObjectTest_ExtendTest1 is built in via $extensions $this->assertTrue( - ExtensionTest::has_extension('SilverStripe\\Core\\Tests\\oBjEcTTEST\\EXTENDTest1'), + ExtensionTest1::has_extension('SilverStripe\\Core\\Tests\\oBjEcTTEST\\EXTENDTest1'), "Extensions are detected when set on Object::\$extensions on has_extension() without case-sensitivity" ); $this->assertTrue( - ExtensionTest::has_extension(ExtendTest1::class), + ExtensionTest1::has_extension(ExtendTest1::class), "Extensions are detected when set on Object::\$extensions on has_extension() without case-sensitivity" ); $this->assertTrue( - singleton(ExtensionTest::class)->hasExtension(ExtendTest1::class), + singleton(ExtensionTest1::class)->hasExtension(ExtendTest1::class), "Extensions are detected when set on Object::\$extensions on instance hasExtension() without" . " case-sensitivity" ); // ObjectTest_ExtendTest2 is built in via $extensions (with parameters) $this->assertTrue( - ExtensionTest::has_extension(ExtendTest2::class), + ExtensionTest1::has_extension(ExtendTest2::class), "Extensions are detected with static has_extension() when set on Object::\$extensions with" . " additional parameters" ); $this->assertTrue( - singleton(ExtensionTest::class)->hasExtension(ExtendTest2::class), + singleton(ExtensionTest1::class)->hasExtension(ExtendTest2::class), "Extensions are detected with instance hasExtension() when set on Object::\$extensions with" . " additional parameters" ); $this->assertFalse( - ExtensionTest::has_extension(ExtendTest3::class), + ExtensionTest1::has_extension(ExtendTest3::class), "Other extensions available in the system are not present unless explicitly added to this object" . " when checking through has_extension()" ); $this->assertFalse( - singleton(ExtensionTest::class)->hasExtension(ExtendTest3::class), + singleton(ExtensionTest1::class)->hasExtension(ExtendTest3::class), "Other extensions available in the system are not present unless explicitly added to this object" . " when checking through instance hasExtension()" ); // ObjectTest_ExtendTest3 is added manually - ExtensionTest::add_extension(ExtendTest3::class . '("Param")'); + ExtensionTest1::add_extension(ExtendTest3::class . '("Param")'); $this->assertTrue( - ExtensionTest::has_extension(ExtendTest3::class), + ExtensionTest1::has_extension(ExtendTest3::class), "Extensions are detected with static has_extension() when added through add_extension()" ); // ExtendTest4 is added manually @@ -235,7 +235,7 @@ public function testHasAndAddExtension() "Sub-Extensions are detected with static has_extension() when added through add_extension()" ); // a singleton() wouldn't work as its already initialized - $objectTest_ExtensionTest = new ExtensionTest(); + $objectTest_ExtensionTest = new ExtensionTest1(); $this->assertTrue( $objectTest_ExtensionTest->hasExtension(ExtendTest3::class), "Extensions are detected with instance hasExtension() when added through add_extension()" @@ -248,37 +248,37 @@ public function testHasAndAddExtension() "Injected sub-extensions are detected with static has_extension() when added through add_extension()" ); - ExtensionTest::remove_extension(ExtendTest3::class); + ExtensionTest1::remove_extension(ExtendTest3::class); } public function testRemoveExtension() { // manually add ObjectTest_ExtendTest2 - ObjectTest\ExtensionRemoveTest::add_extension(ExtendTest2::class); + ObjectTest\ExtensionRemoveTest1::add_extension(ExtendTest2::class); $this->assertTrue( - ObjectTest\ExtensionRemoveTest::has_extension(ExtendTest2::class), + ObjectTest\ExtensionRemoveTest1::has_extension(ExtendTest2::class), "Extension added through \$add_extension() are added correctly" ); - ObjectTest\ExtensionRemoveTest::remove_extension(ExtendTest2::class); + ObjectTest\ExtensionRemoveTest1::remove_extension(ExtendTest2::class); $this->assertFalse( - ObjectTest\ExtensionRemoveTest::has_extension(ExtendTest2::class), + ObjectTest\ExtensionRemoveTest1::has_extension(ExtendTest2::class), "Extension added through \$add_extension() are detected as removed in has_extension()" ); $this->assertFalse( - singleton(ExtensionRemoveTest::class)->hasExtension(ExtendTest2::class), + singleton(ExtensionRemoveTest1::class)->hasExtension(ExtendTest2::class), "Extensions added through \$add_extension() are detected as removed in instances through hasExtension()" ); // ObjectTest_ExtendTest1 is already present in $extensions - ObjectTest\ExtensionRemoveTest::remove_extension(ExtendTest1::class); + ObjectTest\ExtensionRemoveTest1::remove_extension(ExtendTest1::class); $this->assertFalse( - ObjectTest\ExtensionRemoveTest::has_extension(ExtendTest1::class), + ObjectTest\ExtensionRemoveTest1::has_extension(ExtendTest1::class), "Extension added through \$extensions are detected as removed in has_extension()" ); - $objectTest_ExtensionRemoveTest = new ObjectTest\ExtensionRemoveTest(); + $objectTest_ExtensionRemoveTest = new ObjectTest\ExtensionRemoveTest1(); $this->assertFalse( $objectTest_ExtensionRemoveTest->hasExtension(ExtendTest1::class), "Extensions added through \$extensions are detected as removed in instances through hasExtension()" @@ -287,20 +287,20 @@ public function testRemoveExtension() public function testRemoveExtensionWithParameters() { - ObjectTest\ExtensionRemoveTest::add_extension(ExtendTest2::class . '("MyParam")'); + ObjectTest\ExtensionRemoveTest1::add_extension(ExtendTest2::class . '("MyParam")'); $this->assertTrue( - ObjectTest\ExtensionRemoveTest::has_extension(ExtendTest2::class), + ObjectTest\ExtensionRemoveTest1::has_extension(ExtendTest2::class), "Extension added through \$add_extension() are added correctly" ); - ObjectTest\ExtensionRemoveTest::remove_extension(ExtendTest2::class); + ObjectTest\ExtensionRemoveTest1::remove_extension(ExtendTest2::class); $this->assertFalse( - ExtensionRemoveTest::has_extension(ExtendTest2::class), + ExtensionRemoveTest1::has_extension(ExtendTest2::class), "Extension added through \$add_extension() are detected as removed in has_extension()" ); - $objectTest_ExtensionRemoveTest = new ObjectTest\ExtensionRemoveTest(); + $objectTest_ExtensionRemoveTest = new ObjectTest\ExtensionRemoveTest1(); $this->assertFalse( $objectTest_ExtensionRemoveTest->hasExtension(ExtendTest2::class), "Extensions added through \$extensions are detected as removed in instances through hasExtension()" @@ -326,7 +326,7 @@ public function testExtInstance() public function testExtend() { - $object = new ObjectTest\ExtendTest(); + $object = new ObjectTest\ExtendTestBase(); $argument = 'test'; $this->assertEquals($object->extend('extendableMethod'), ['ExtendTest2()']); @@ -334,13 +334,13 @@ public function testExtend() $this->assertEquals($argument, 'modified'); $this->assertEquals( - ['ExtendTest()', 'ExtendTest2()'], + ['ExtendTestBase()', 'ExtendTest2()'], $object->invokeWithExtensions('extendableMethod') ); $arg1 = 'test'; $arg2 = 'bob'; $this->assertEquals( - ['ExtendTest(test,bob)', 'ExtendTest2(modified,objectmodified)'], + ['ExtendTestBase(test,bob)', 'ExtendTest2(modified,objectmodified)'], $object->invokeWithExtensions('extendableMethod', $arg1, $arg2) ); $this->assertEquals('modified', $arg1); diff --git a/tests/php/Core/ObjectTest/CacheTest.php b/tests/php/Core/ObjectTest/CacheTest1.php similarity index 88% rename from tests/php/Core/ObjectTest/CacheTest.php rename to tests/php/Core/ObjectTest/CacheTest1.php index 77b636b718f..b30fcb471d7 100644 --- a/tests/php/Core/ObjectTest/CacheTest.php +++ b/tests/php/Core/ObjectTest/CacheTest1.php @@ -2,7 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -class CacheTest extends BaseObject +class CacheTest1 extends BaseObject { public $count = 0; diff --git a/tests/php/Core/ObjectTest/CreateTest.php b/tests/php/Core/ObjectTest/CreateTest1.php similarity index 85% rename from tests/php/Core/ObjectTest/CreateTest.php rename to tests/php/Core/ObjectTest/CreateTest1.php index 3dfaec71f5f..7a79fb65d34 100644 --- a/tests/php/Core/ObjectTest/CreateTest.php +++ b/tests/php/Core/ObjectTest/CreateTest1.php @@ -2,7 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -class CreateTest extends BaseObject +class CreateTest1 extends BaseObject { public $constructArguments; diff --git a/tests/php/Core/ObjectTest/ExtendTest.php b/tests/php/Core/ObjectTest/ExtendTestBase.php similarity index 82% rename from tests/php/Core/ObjectTest/ExtendTest.php rename to tests/php/Core/ObjectTest/ExtendTestBase.php index 7e513714099..e76b2d07510 100644 --- a/tests/php/Core/ObjectTest/ExtendTest.php +++ b/tests/php/Core/ObjectTest/ExtendTestBase.php @@ -2,7 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -class ExtendTest extends BaseObject +class ExtendTestBase extends BaseObject { private static $extensions = [ ExtendTest1::class, @@ -15,6 +15,6 @@ public function extendableMethod(&$argument = null, &$argument2 = null) if ($argument2) { $argument2 = 'objectmodified'; } - return "ExtendTest($args)"; + return "ExtendTestBase($args)"; } } diff --git a/tests/php/Core/ObjectTest/ExtensionRemoveTest.php b/tests/php/Core/ObjectTest/ExtensionRemoveTest1.php similarity index 73% rename from tests/php/Core/ObjectTest/ExtensionRemoveTest.php rename to tests/php/Core/ObjectTest/ExtensionRemoveTest1.php index 5b8af30645f..e9012b41e84 100644 --- a/tests/php/Core/ObjectTest/ExtensionRemoveTest.php +++ b/tests/php/Core/ObjectTest/ExtensionRemoveTest1.php @@ -2,7 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -class ExtensionRemoveTest extends BaseObject +class ExtensionRemoveTest1 extends BaseObject { private static $extensions = [ ExtendTest1::class, diff --git a/tests/php/Core/ObjectTest/ExtensionTest.php b/tests/php/Core/ObjectTest/ExtensionTest1.php similarity index 85% rename from tests/php/Core/ObjectTest/ExtensionTest.php rename to tests/php/Core/ObjectTest/ExtensionTest1.php index 8f17696e7e2..b6848832231 100644 --- a/tests/php/Core/ObjectTest/ExtensionTest.php +++ b/tests/php/Core/ObjectTest/ExtensionTest1.php @@ -2,7 +2,7 @@ namespace SilverStripe\Core\Tests\ObjectTest; -class ExtensionTest extends BaseObject +class ExtensionTest1 extends BaseObject { private static $extensions = [ 'SilverStripe\\Core\\Tests\\oBjEcTTEST\\EXTENDTest1', diff --git a/tests/php/Core/PathTest.php b/tests/php/Core/PathTest.php index 10dff0e8d98..87b1a716336 100644 --- a/tests/php/Core/PathTest.php +++ b/tests/php/Core/PathTest.php @@ -5,16 +5,17 @@ use InvalidArgumentException; use SilverStripe\Core\Path; use SilverStripe\Dev\SapphireTest; +use PHPUnit\Framework\Attributes\DataProvider; class PathTest extends SapphireTest { /** * Test paths are joined * - * @dataProvider providerTestJoinPaths * @param array $args Arguments to pass to Path::join() * @param string $expected Expected path */ + #[DataProvider('providerTestJoinPaths')] public function testJoinPaths($args, $expected) { $joined = Path::join($args); @@ -26,7 +27,7 @@ public function testJoinPaths($args, $expected) * * @return array */ - public function providerTestJoinPaths() + public static function providerTestJoinPaths() { $tests = [ // Single arg @@ -64,10 +65,10 @@ public function providerTestJoinPaths() /** * Test that joinPaths give the appropriate error * - * @dataProvider providerTestJoinPathsErrors * @param array $args Arguments to pass to Filesystem::joinPath() * @param string $error Expected path */ + #[DataProvider('providerTestJoinPathsErrors')] public function testJoinPathsErrors($args, $error) { $this->expectException(\InvalidArgumentException::class); @@ -75,7 +76,7 @@ public function testJoinPathsErrors($args, $error) Path::join($args); } - public function providerTestJoinPathsErrors() + public static function providerTestJoinPathsErrors() { return [ [['/base', '../passwd'], 'Can not collapse relative folders'], @@ -87,17 +88,17 @@ public function providerTestJoinPathsErrors() } /** - * @dataProvider providerTestNormalise * @param string $input * @param string $expected */ + #[DataProvider('providerTestNormalise')] public function testNormalise($input, $expected) { $output = Path::normalise($input); $this->assertEquals($expected, $output, "Expected $input to be normalised to $expected"); } - public function providerTestNormalise() + public static function providerTestNormalise() { $tests = [ // Windows paths diff --git a/tests/php/Core/Validation/ConstraintValidatorTest.php b/tests/php/Core/Validation/ConstraintValidatorTest.php index 074340cfb73..e2dc9aaab6e 100644 --- a/tests/php/Core/Validation/ConstraintValidatorTest.php +++ b/tests/php/Core/Validation/ConstraintValidatorTest.php @@ -60,12 +60,13 @@ use Symfony\Component\Validator\Constraints\Unique; use Symfony\Component\Validator\Constraints\Url; use Symfony\Component\Validator\Constraints\Uuid; +use PHPUnit\Framework\Attributes\DataProvider; class ConstraintValidatorTest extends SapphireTest { protected $usesDatabase = false; - public function provideValidate(): array + public static function provideValidate(): array { $scenarios = [ // basic @@ -309,15 +310,14 @@ public function provideValidate(): array * * We're not actually testing the validation logic per se - just testing that the validators * all do some validating (hence why they are all set to fail) without exceptions being thrown. - * - * @dataProvider provideValidate */ + #[DataProvider('provideValidate')] public function testValidate(mixed $value, Constraint $constraint): void { $this->assertFalse(ConstraintValidator::validate($value, $constraint)->isValid()); } - public function provideValidateResults(): array + public static function provideValidateResults(): array { return [ 'single constraint, no field' => [ @@ -343,9 +343,7 @@ public function provideValidateResults(): array ]; } - /** - * @dataProvider provideValidateResults - */ + #[DataProvider('provideValidateResults')] public function testValidateResults(mixed $value, Constraint|array $constraints, string $fieldName): void { $result = ConstraintValidator::validate($value, $constraints, $fieldName); diff --git a/tests/php/Dev/BacktraceTest.php b/tests/php/Dev/BacktraceTest.php index d1f5fe98d24..2435ab5c8b4 100644 --- a/tests/php/Dev/BacktraceTest.php +++ b/tests/php/Dev/BacktraceTest.php @@ -9,6 +9,7 @@ use SilverStripe\Dev\Backtrace; use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\DataObject; +use PHPUnit\Framework\Attributes\DataProvider; class BacktraceTest extends SapphireTest { @@ -115,7 +116,7 @@ public function testFilteredWildCard() $this->assertEquals('myval', $filtered[2]['args']['myarg']); } - public function matchesFilterableClassProvider(): array + public static function matchesFilterableClassProvider(): array { return [ [ @@ -157,9 +158,7 @@ public function matchesFilterableClassProvider(): array ]; } - /** - * @dataProvider matchesFilterableClassProvider - */ + #[DataProvider('matchesFilterableClassProvider')] public function testMatchesFilterableClass(string $className, string $filterableClass, bool $expected, string $message): void { $reflectionMethod = new ReflectionMethod(Backtrace::class . '::matchesFilterableClass'); diff --git a/tests/php/Dev/CsvBulkLoaderTest.php b/tests/php/Dev/CsvBulkLoaderTest.php index c5d384274a0..7d0d000c801 100644 --- a/tests/php/Dev/CsvBulkLoaderTest.php +++ b/tests/php/Dev/CsvBulkLoaderTest.php @@ -17,6 +17,7 @@ use SilverStripe\Dev\Tests\CsvBulkLoaderTest\CantCreateModel; use SilverStripe\Dev\Tests\CsvBulkLoaderTest\CantDeleteModel; use SilverStripe\Dev\Tests\CsvBulkLoaderTest\CantEditModel; +use PHPUnit\Framework\Attributes\DataProvider; class CsvBulkLoaderTest extends SapphireTest { @@ -345,9 +346,7 @@ public function testLargeFileSplitIntoSmallerFiles() $this->assertCount(10, $results); } - /** - * @dataProvider provideCheckPermissions - */ + #[DataProvider('provideCheckPermissions')] public function testCheckPermissions(string $class, string $file, bool $respectPerms, string $exceptionMessage) { $loader = new CsvBulkLoader($class); @@ -370,7 +369,7 @@ public function testCheckPermissions(string $class, string $file, bool $respectP } } - public function provideCheckPermissions() + public static function provideCheckPermissions() { $scenarios = [ 'Has all permissions' => [ diff --git a/tests/php/Dev/DeprecationTest.php b/tests/php/Dev/DeprecationTest.php index 30d6b2018f3..02c6f08d79a 100644 --- a/tests/php/Dev/DeprecationTest.php +++ b/tests/php/Dev/DeprecationTest.php @@ -9,9 +9,12 @@ use SilverStripe\Core\Environment; use SilverStripe\Dev\Deprecation; use SilverStripe\Dev\SapphireTest; +use SilverStripe\Dev\Tests\DeprecationTest\DeprecationTestException; use SilverStripe\Dev\Tests\DeprecationTest\DeprecationTestObject; use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Kernel; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\DoesNotPerformAssertions; class DeprecationTest extends SapphireTest { @@ -27,14 +30,14 @@ protected function setup(): void { // Use custom error handler for two reasons: // - Filter out errors for deprecated class properties unrelated to this unit test - // - Allow the use of expectDeprecation(), which doesn't work with E_USER_DEPRECATION by default + // - Allow the use of expectException(), which doesn't work with E_USER_DEPRECATION by default // https://github.com/laminas/laminas-di/pull/30#issuecomment-927585210 parent::setup(); $this->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 +76,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 +93,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 +108,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 +133,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 +150,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 +167,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 +183,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,16 +200,14 @@ 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(); } - /** - * @doesNotPerformAssertions - */ + #[DoesNotPerformAssertions] public function testDisabled() { if ($this->noticesWereEnabled) { @@ -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,14 +279,14 @@ 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(); } - public function provideConfigVsEnv() + public static function provideConfigVsEnv() { return [ // env var not set - config setting is respected @@ -326,25 +327,19 @@ public function provideConfigVsEnv() ]; } - /** - * @dataProvider provideConfigVsEnv - */ + #[DataProvider('provideConfigVsEnv')] public function testEnabledConfigVsEnv($envVal, bool $configVal, bool $expected) { $this->runConfigVsEnvTest('SS_DEPRECATION_ENABLED', $envVal, $configVal, $expected); } - /** - * @dataProvider provideConfigVsEnv - */ + #[DataProvider('provideConfigVsEnv')] public function testShowHttpConfigVsEnv($envVal, bool $configVal, bool $expected) { $this->runConfigVsEnvTest('SS_DEPRECATION_SHOW_HTTP', $envVal, $configVal, $expected); } - /** - * @dataProvider provideConfigVsEnv - */ + #[DataProvider('provideConfigVsEnv')] public function testShowCliConfigVsEnv($envVal, bool $configVal, bool $expected) { $this->runConfigVsEnvTest('SS_DEPRECATION_SHOW_CLI', $envVal, $configVal, $expected); @@ -391,7 +386,7 @@ private function runConfigVsEnvTest(string $varName, $envVal, bool $configVal, b $this->assertSame($expected, $result); } - public function provideVarAsBoolean() + public static function provideVarAsBoolean() { return [ [ @@ -437,9 +432,7 @@ public function provideVarAsBoolean() ]; } - /** - * @dataProvider provideVarAsBoolean - */ + #[DataProvider('provideVarAsBoolean')] public function testVarAsBoolean($rawValue, bool $expected) { $reflectionVarAsBoolean = new ReflectionMethod(Deprecation::class, 'varAsBoolean'); @@ -448,7 +441,7 @@ public function testVarAsBoolean($rawValue, bool $expected) $this->assertSame($expected, $reflectionVarAsBoolean->invoke(null, $rawValue)); } - public function provideIsEnabled() + public static function provideIsEnabled() { return [ 'dev, explicitly enabled' => [ @@ -514,9 +507,7 @@ public function provideIsEnabled() ]; } - /** - * @dataProvider provideIsEnabled - */ + #[DataProvider('provideIsEnabled')] public function testIsEnabled(string $envMode, ?bool $envEnabled, bool $staticEnabled, bool $expected) { /** @var Kernel $kernel */ 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 @@ +assertEquals(true, $this->getAndCheckForError('/dev/x2')); } - /** - * @dataProvider getLinksPermissionsProvider - */ + #[DataProvider('getLinksPermissionsProvider')] public function testGetLinks(string $permission, array $present, array $absent): void { DevelopmentAdmin::config()->set('allow_all_cli', false); @@ -94,7 +93,7 @@ public function testGetLinks(string $permission, array $present, array $absent): } } - protected function getLinksPermissionsProvider() : array + public static function getLinksPermissionsProvider() : array { return [ ['ADMIN', ['x1', 'x1/y1', 'x3'], ['x2']], diff --git a/tests/php/Dev/SSListContainsOnlyTest.php b/tests/php/Dev/SSListContainsOnlyTest.php index bd3110f842f..3f184175ab6 100644 --- a/tests/php/Dev/SSListContainsOnlyTest.php +++ b/tests/php/Dev/SSListContainsOnlyTest.php @@ -6,10 +6,11 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\ArrayList; use SilverStripe\Security\Member; +use PHPUnit\Framework\Attributes\DataProvider; class SSListContainsOnlyTest extends SapphireTest { - public function provideMatchesForList() + public static function provideMatchesForList() { return [ [ @@ -28,7 +29,7 @@ public function provideMatchesForList() } - public function provideInvalidMatchesForList() + public static function provideInvalidMatchesForList() { return [ [ @@ -50,10 +51,9 @@ public function provideInvalidMatchesForList() } /** - * @dataProvider provideMatchesForList() - * * @param $matches */ + #[DataProvider('provideMatchesForList')] public function testEvaluateListMatchesCorrectly($matches) { $constraint = new SSListContainsOnly($matches); @@ -74,10 +74,9 @@ private function getListToMatch() } /** - * @dataProvider provideInvalidMatchesForList() - * * @param $matches */ + #[DataProvider('provideInvalidMatchesForList')] public function testEvaluateListDoesNotMatchWrongMatches($matches) { $constraint = new SSListContainsOnly($matches); diff --git a/tests/php/Dev/SSListContainsTest.php b/tests/php/Dev/SSListContainsTest.php index 6d9a28ba1f9..0c79553129a 100644 --- a/tests/php/Dev/SSListContainsTest.php +++ b/tests/php/Dev/SSListContainsTest.php @@ -6,10 +6,11 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\ArrayList; use SilverStripe\Security\Member; +use PHPUnit\Framework\Attributes\DataProvider; class SSListContainsTest extends SapphireTest { - public function provideMatchesForList() + public static function provideMatchesForList() { return [ [ @@ -31,7 +32,7 @@ public function provideMatchesForList() } - public function provideInvalidMatchesForList() + public static function provideInvalidMatchesForList() { return [ [ @@ -53,10 +54,9 @@ public function provideInvalidMatchesForList() } /** - * @dataProvider provideMatchesForList() - * * @param $matches */ + #[DataProvider('provideMatchesForList')] public function testEvaluateListMatchesCorrectly($matches) { $constraint = new SSListContains($matches); @@ -65,10 +65,9 @@ public function testEvaluateListMatchesCorrectly($matches) } /** - * @dataProvider provideInvalidMatchesForList() - * * @param $matches */ + #[DataProvider('provideInvalidMatchesForList')] public function testEvaluateListDoesNotMatchWrongMatches($matches) { $constraint = new SSListContains($matches); diff --git a/tests/php/Dev/SSListExporterTest.php b/tests/php/Dev/SSListExporterTest.php deleted file mode 100644 index 64edc3b188f..00000000000 --- a/tests/php/Dev/SSListExporterTest.php +++ /dev/null @@ -1,86 +0,0 @@ -exporter = new SSListExporter(); - } - - public function provideClassesForExport() - { - return [ - [ArrayList::class, false], - [DataObject::class, false], - [DataList::class, Member::class], - [ArrayData::class, false] - ]; - } - - /** - * @dataProvider provideClassesForExport() - * @param $className - * @param $constructorParam - */ - public function testExportStartsWithClassName($className, $constructorParam) - { - $obj = $constructorParam - ? $className::create($constructorParam) - : $className::create(); - - $export = ltrim($this->exporter->export($obj) ?? ''); - - $this->assertStringStartsWith(get_class($obj), $export, 'Export should start with object\'s class name'); - } - - - /** - * @testdox toMap() returns DataObjects's data - */ - public function testToMapReturnsDataOfDataObjects() - { - $data = [ - 'ID' => 5, - 'Foo' => 'Bar', - 'Baz' => 'Boom', - 'One' => 'Two' - ]; - - $map = $this->exporter->toMap(DataObject::create($data, DataObject::CREATE_HYDRATED)); - - $this->assertEquals($data, $map, 'Map should match data passed to DataObject'); - } - - /** - * @testdox toMap() returns ArrayData's data - */ - public function testToMapReturnsDataOfArrayData() - { - $data = [ - 'Foo' => 'Bar', - 'Baz' => 'Boom', - 'One' => 'Two' - ]; - - $map = $this->exporter->toMap(ArrayData::create($data)); - - $this->assertEquals($data, $map, 'Map should match data passed to ArrayData'); - } -} diff --git a/tests/php/Dev/SapphireTestTest.php b/tests/php/Dev/SapphireTestTest.php index 3b571c3c1ae..94d53bef123 100644 --- a/tests/php/Dev/SapphireTestTest.php +++ b/tests/php/Dev/SapphireTestTest.php @@ -7,14 +7,22 @@ use SilverStripe\ORM\ArrayList; use SilverStripe\Security\Member; use SilverStripe\Security\Permission; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\DataProviderExternal; +use SilverStripe\Dev\Exceptions\ExpectedErrorException; +use SilverStripe\Dev\Exceptions\ExpectedNoticeException; +use SilverStripe\Dev\Exceptions\ExpectedWarningException; +/** + * @sometag This is a test annotation used in the testGetAnnotations test + */ class SapphireTestTest extends SapphireTest { /** * @return array */ - public function provideResolveFixturePath() + public static function provideResolveFixturePath() { return [ 'sameDirectory' => [ @@ -40,9 +48,7 @@ public function provideResolveFixturePath() ]; } - /** - * @dataProvider provideResolveFixturePath - */ + #[DataProvider('provideResolveFixturePath')] public function testResolveFixturePath($expected, $path, $message) { $this->assertEquals( @@ -86,13 +92,10 @@ public function testCreateMemberWithPermission() } /** - * @dataProvider \SilverStripe\Dev\Tests\SapphireTestTest\DataProvider::provideAllMatchingList() - * * @param $match * @param $itemsForList - * - * @testdox Has assertion assertListAllMatch */ + #[DataProviderExternal('\SilverStripe\Dev\Tests\SapphireTestTest\DataProvider', 'provideAllMatchingList')] public function testAssertListAllMatch($match, $itemsForList, $message) { $list = $this->generateArrayListFromItems($itemsForList); @@ -117,13 +120,10 @@ private function generateArrayListFromItems($itemsForList) } /** - * @dataProvider \SilverStripe\Dev\Tests\SapphireTestTest\DataProvider::provideNotMatchingList() - * * @param $match * @param $itemsForList - * - * @testdox assertion assertListAllMatch fails when not all items are matching */ + #[DataProviderExternal('\SilverStripe\Dev\Tests\SapphireTestTest\DataProvider', 'provideNotMatchingList')] public function testAssertListAllMatchFailsWhenNotMatchingAllItems($match, $itemsForList) { $this->expectException(ExpectationFailedException::class); @@ -133,13 +133,10 @@ public function testAssertListAllMatchFailsWhenNotMatchingAllItems($match, $item } /** - * @dataProvider \SilverStripe\Dev\Tests\SapphireTestTest\DataProvider::provideEqualListsWithEmptyList() - * * @param $matches * @param $itemsForList - * - * @testdox Has assertion assertListContains */ + #[DataProviderExternal('\SilverStripe\Dev\Tests\SapphireTestTest\DataProvider', 'provideEqualListsWithEmptyList')] public function testAssertListContains($matches, $itemsForList) { $list = $this->generateArrayListFromItems($itemsForList); @@ -151,12 +148,10 @@ public function testAssertListContains($matches, $itemsForList) } /** - * @dataProvider \SilverStripe\Dev\Tests\SapphireTestTest\DataProvider::provideNotContainingList - * @testdox assertion assertListEquals fails on non equal Lists - * * @param $matches * @param $itemsForList array */ + #[DataProviderExternal('\SilverStripe\Dev\Tests\SapphireTestTest\DataProvider', 'provideNotContainingList')] public function testAssertListContainsFailsIfListDoesNotContainMatch($matches, $itemsForList) { $this->expectException(ExpectationFailedException::class); @@ -169,13 +164,10 @@ public function testAssertListContainsFailsIfListDoesNotContainMatch($matches, $ } /** - * @dataProvider \SilverStripe\Dev\Tests\SapphireTestTest\DataProvider::provideNotContainingList - * - * @testdox Has assertion assertListNotContains - * * @param $matches * @param $itemsForList */ + #[DataProviderExternal('\SilverStripe\Dev\Tests\SapphireTestTest\DataProvider', 'provideNotContainingList')] public function testAssertListNotContains($matches, $itemsForList) { $list = $this->generateArrayListFromItems($itemsForList); @@ -184,13 +176,10 @@ public function testAssertListNotContains($matches, $itemsForList) } /** - * @dataProvider \SilverStripe\Dev\Tests\SapphireTestTest\DataProvider::provideEqualLists - * * @param $matches * @param $itemsForList - * - * @testdox assertion assertListNotContains throws a exception when a matching item is found in the list */ + #[DataProviderExternal('\SilverStripe\Dev\Tests\SapphireTestTest\DataProvider', 'provideEqualLists')] public function testAssertListNotContainsFailsWhenListContainsAMatch($matches, $itemsForList) { $this->expectException(ExpectationFailedException::class); @@ -203,12 +192,10 @@ public function testAssertListNotContainsFailsWhenListContainsAMatch($matches, $ } /** - * @dataProvider \SilverStripe\Dev\Tests\SapphireTestTest\DataProvider::provideEqualListsWithEmptyList() - * @testdox Has assertion assertListEquals - * * @param $matches * @param $itemsForList */ + #[DataProviderExternal('\SilverStripe\Dev\Tests\SapphireTestTest\DataProvider', 'provideEqualListsWithEmptyList')] public function testAssertListEquals($matches, $itemsForList) { $list = $this->generateArrayListFromItems($itemsForList); @@ -217,12 +204,10 @@ public function testAssertListEquals($matches, $itemsForList) } /** - * @dataProvider \SilverStripe\Dev\Tests\SapphireTestTest\DataProvider::provideNonEqualLists - * @testdox assertion assertListEquals fails on non equal Lists - * * @param $matches * @param $itemsForList */ + #[DataProviderExternal('\SilverStripe\Dev\Tests\SapphireTestTest\DataProvider', 'provideNonEqualLists')] public function testAssertListEqualsFailsOnNonEqualLists($matches, $itemsForList) { $this->expectException(ExpectationFailedException::class); @@ -230,4 +215,79 @@ public function testAssertListEqualsFailsOnNonEqualLists($matches, $itemsForList $this->assertListEquals($matches, $list); } + + /** + * This test intentionally has non-sensical annotations to test the parser + * + * @lorem ipsum + * @param $one something + * @param $two else + */ + public function testGetAnnotations(): void + { + $this->assertSame([ + 'method' => [ + 'lorem' => [ + 'ipsum' + ], + 'param' => [ + '$one something', + '$two else', + ], + ], + 'class' => [ + 'sometag' => [ + 'This is a test annotation used in the testGetAnnotations test' + ], + ], + ], $this->getAnnotations()); + } + + #[DataProvider('provideEnableErrorHandler')] + public function testEnableErrorHandler(int $errno, ?string $expectedClass): void + { + $this->enableErrorHandler(); + $bool = false; + if ($expectedClass) { + $this->expectException($expectedClass); + $this->expectExceptionMessage('test'); + } + if ($errno === E_USER_DEPRECATED) { + // Prevent deprecation notices from being displayed + set_error_handler(function ($errno, $errstr) use (&$bool) { + if ($errno === E_USER_DEPRECATED) { + $bool = true; + } + }); + trigger_error('test', $errno); + } + trigger_error('test', $errno); + if ($errno === E_USER_DEPRECATED) { + restore_error_handler(); + $this->assertTrue($bool); + } + } + + public static function provideEnableErrorHandler(): array + { + // Only E_USER_* errors can be triggered, so that's all that's being tested + return [ + 'error' => [ + 'errno' => E_USER_ERROR, + 'expectedClass' => ExpectedErrorException::class, + ], + 'notice' => [ + 'errno' => E_USER_NOTICE, + 'expectedClass' => ExpectedNoticeException::class, + ], + 'warning' => [ + 'errno' => E_USER_WARNING, + 'expectedClass' => ExpectedWarningException::class, + ], + 'deprecated' => [ + 'errno' => E_USER_DEPRECATED, + 'expectedClass' => null, + ], + ]; + } } diff --git a/tests/php/Dev/Validation/RelationValidationTest.php b/tests/php/Dev/Validation/RelationValidationTest.php index 04f57c4af41..9e2b673f9f3 100644 --- a/tests/php/Dev/Validation/RelationValidationTest.php +++ b/tests/php/Dev/Validation/RelationValidationTest.php @@ -8,6 +8,7 @@ use SilverStripe\Dev\Validation\RelationValidationService; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObjectSchema; +use PHPUnit\Framework\Attributes\DataProvider; class RelationValidationTest extends SapphireTest { @@ -26,8 +27,8 @@ class RelationValidationTest extends SapphireTest * @param string|null $field * @param array $value * @param array $expected - * @dataProvider validateCasesProvider */ + #[DataProvider('validateCasesProvider')] public function testValidation(?string $class, ?string $field, array $value, array $expected): void { if ($class && $field) { @@ -49,8 +50,8 @@ public function testValidation(?string $class, ?string $field, array $value, arr * @param string|null $relation * @param array $config * @param bool $expected - * @dataProvider ignoredClassesProvider */ + #[DataProvider('ignoredClassesProvider')] public function testIgnoredClass(string $class, ?string $relation, array $config, bool $expected): void { if (!class_exists($class)) { @@ -67,7 +68,7 @@ public function testIgnoredClass(string $class, ?string $relation, array $config $this->assertEquals($expected, $result); } - public function validateCasesProvider(): array + public static function validateCasesProvider(): array { return [ 'correct setup' => [ @@ -272,7 +273,7 @@ public function validateCasesProvider(): array ]; } - public function ignoredClassesProvider(): array + public static function ignoredClassesProvider(): array { return [ 'class default' => [ diff --git a/tests/php/Dev/ViewableDataContainsTest.php b/tests/php/Dev/ViewableDataContainsTest.php index fcf93c26e06..bbfe2c22f3f 100644 --- a/tests/php/Dev/ViewableDataContainsTest.php +++ b/tests/php/Dev/ViewableDataContainsTest.php @@ -7,6 +7,7 @@ use SilverStripe\Dev\Tests\ViewableDataContainsTest\TestObject; use SilverStripe\Security\Member; use SilverStripe\View\ArrayData; +use PHPUnit\Framework\Attributes\DataProvider; class ViewableDataContainsTest extends SapphireTest { @@ -15,7 +16,7 @@ class ViewableDataContainsTest extends SapphireTest 'Surname' => 'Schommer' ]; - public function provideMatchesForList() + public static function provideMatchesForList() { return [ [ @@ -31,7 +32,7 @@ public function provideMatchesForList() } - public function provideInvalidMatchesForList() + public static function provideInvalidMatchesForList() { return [ [ @@ -47,10 +48,9 @@ public function provideInvalidMatchesForList() } /** - * @dataProvider provideMatchesForList() - * * @param $match */ + #[DataProvider('provideMatchesForList')] public function testEvaluateMatchesCorrectlyArrayData($match) { $constraint = new ViewableDataContains($match); @@ -61,10 +61,9 @@ public function testEvaluateMatchesCorrectlyArrayData($match) } /** - * @dataProvider provideMatchesForList() - * * @param $match */ + #[DataProvider('provideMatchesForList')] public function testEvaluateMatchesCorrectlyDataObject($match) { $constraint = new ViewableDataContains($match); @@ -75,10 +74,9 @@ public function testEvaluateMatchesCorrectlyDataObject($match) } /** - * @dataProvider provideInvalidMatchesForList() - * * @param $matches */ + #[DataProvider('provideInvalidMatchesForList')] public function testEvaluateDoesNotMatchWrongMatchInArrayData($match) { $constraint = new ViewableDataContains($match); @@ -89,10 +87,9 @@ public function testEvaluateDoesNotMatchWrongMatchInArrayData($match) } /** - * @dataProvider provideInvalidMatchesForList() - * * @param $matches */ + #[DataProvider('provideInvalidMatchesForList')] public function testEvaluateDoesNotMatchWrongMatchInDataObject($match) { $constraint = new ViewableDataContains($match); diff --git a/tests/php/Forms/ConfirmedPasswordFieldTest.php b/tests/php/Forms/ConfirmedPasswordFieldTest.php index 971ad371672..ac614dc4bd3 100644 --- a/tests/php/Forms/ConfirmedPasswordFieldTest.php +++ b/tests/php/Forms/ConfirmedPasswordFieldTest.php @@ -14,6 +14,7 @@ use SilverStripe\Security\PasswordValidator; use SilverStripe\View\SSViewer; use Closure; +use PHPUnit\Framework\Attributes\DataProvider; class ConfirmedPasswordFieldTest extends SapphireTest { @@ -185,8 +186,8 @@ public function testFormValidation() * @param int|null $maxLength * @param bool $expectValid * @param string $expectedMessage - * @dataProvider lengthValidationProvider */ + #[DataProvider('lengthValidationProvider')] public function testLengthValidation($minLength, $maxLength, $expectValid, $expectedMessage = '') { $field = new ConfirmedPasswordField('Test', 'Testing', [ @@ -208,7 +209,7 @@ public function testLengthValidation($minLength, $maxLength, $expectValid, $expe /** * @return array[] */ - public function lengthValidationProvider() + public static function lengthValidationProvider() { return [ 'valid: within min and max' => [3, 8, true], @@ -385,9 +386,7 @@ public function testSetRequireExistingPasswordOnlyRunsOnce() $this->assertCount(2, $field->getChildren(), 'Current password field should not be removed'); } - /** - * @dataProvider provideSetCanBeEmptySaveInto - */ + #[DataProvider('provideSetCanBeEmptySaveInto')] public function testSetCanBeEmptySaveInto(bool $generateRandomPasswordOnEmpty, ?string $expected) { $field = new ConfirmedPasswordField('Test', 'Change it'); @@ -403,7 +402,7 @@ public function testSetCanBeEmptySaveInto(bool $generateRandomPasswordOnEmpty, ? $this->assertSame($expected, $field->Value()); } - public function provideSetCanBeEmptySaveInto(): array + public static function provideSetCanBeEmptySaveInto(): array { return [ [ @@ -430,7 +429,7 @@ public function testSetCanBeEmptyRightTitle() $this->assertNotEmpty($passwordField->RightTitle()); } - public function provideRequired() + public static function provideRequired() { return [ 'can be empty' => [true], @@ -438,9 +437,7 @@ public function provideRequired() ]; } - /** - * @dataProvider provideRequired - */ + #[DataProvider('provideRequired')] public function testRequired(bool $canBeEmpty) { $field = new ConfirmedPasswordField('Test'); @@ -448,7 +445,7 @@ public function testRequired(bool $canBeEmpty) $this->assertSame(!$canBeEmpty, $field->Required()); } - public function provideChildFieldsAreRequired() + public static function provideChildFieldsAreRequired() { return [ 'not required' => [ @@ -478,9 +475,7 @@ public function provideChildFieldsAreRequired() ]; } - /** - * @dataProvider provideChildFieldsAreRequired - */ + #[DataProvider('provideChildFieldsAreRequired')] public function testChildFieldsAreRequired(bool $canBeEmpty, bool $required, bool $childrenRequired, bool $expectRequired) { // CWP front-end templates break this logic - but there's no easy fix for that. diff --git a/tests/php/Forms/DatalessFieldTest.php b/tests/php/Forms/DatalessFieldTest.php index abfdf54acbd..cd7c86cebe6 100644 --- a/tests/php/Forms/DatalessFieldTest.php +++ b/tests/php/Forms/DatalessFieldTest.php @@ -19,7 +19,7 @@ public function testFieldHolderAndSmallFieldHolderReturnField() /** @var DatalessField|MockObject $mock */ $mock = $this->getMockBuilder(DatalessField::class) ->disableOriginalConstructor() - ->setMethods(['Field']) + ->onlyMethods(['Field']) ->getMock(); $properties = [ diff --git a/tests/php/Forms/DropdownFieldTest.php b/tests/php/Forms/DropdownFieldTest.php index 88603aa7550..a83ea816ea8 100644 --- a/tests/php/Forms/DropdownFieldTest.php +++ b/tests/php/Forms/DropdownFieldTest.php @@ -13,6 +13,7 @@ use SilverStripe\Forms\Form; use SilverStripe\View\ArrayData; use SilverStripe\ORM\Map; +use PHPUnit\Framework\Attributes\DataProvider; class DropdownFieldTest extends SapphireTest { @@ -410,9 +411,8 @@ public function testNumberOfDisabledOptions() /** * The Field() method should be able to handle arrays as values in an edge case. If it couldn't handle it then * this test would trigger an array to string conversion PHP notice - * - * @dataProvider arrayValueProvider */ + #[DataProvider('arrayValueProvider')] public function testDropdownWithArrayValues($value) { $field = $this->createDropdownField(); @@ -424,7 +424,7 @@ public function testDropdownWithArrayValues($value) /** * @return array */ - public function arrayValueProvider() + public static function arrayValueProvider() { return [ [[]], diff --git a/tests/php/Forms/FieldsValidatorTest.php b/tests/php/Forms/FieldsValidatorTest.php index 8c958bcd348..d5eac24d9c4 100644 --- a/tests/php/Forms/FieldsValidatorTest.php +++ b/tests/php/Forms/FieldsValidatorTest.php @@ -7,12 +7,13 @@ use SilverStripe\Forms\FieldList; use SilverStripe\Forms\FieldsValidator; use SilverStripe\Forms\Form; +use PHPUnit\Framework\Attributes\DataProvider; class FieldsValidatorTest extends SapphireTest { protected $usesDatabase = false; - public function provideValidation() + public static function provideValidation() { return [ 'missing values arent invalid' => [ @@ -50,9 +51,7 @@ public function provideValidation() ]; } - /** - * @dataProvider provideValidation - */ + #[DataProvider('provideValidation')] public function testValidation(array $values, bool $isValid) { $fieldList = new FieldList([ diff --git a/tests/php/Forms/FileFieldTest.php b/tests/php/Forms/FileFieldTest.php index 18e397d30f5..d4a170010c0 100644 --- a/tests/php/Forms/FileFieldTest.php +++ b/tests/php/Forms/FileFieldTest.php @@ -16,7 +16,6 @@ class FileFieldTest extends FunctionalTest { /** * Test a valid upload of a required file in a form. Error is set to 0, as the upload went well - * */ public function testUploadRequiredFile() { diff --git a/tests/php/Forms/FormFieldTest.php b/tests/php/Forms/FormFieldTest.php index 21b4a01283a..8050f1c64ac 100644 --- a/tests/php/Forms/FormFieldTest.php +++ b/tests/php/Forms/FormFieldTest.php @@ -38,6 +38,7 @@ use SilverStripe\Security\PermissionCheckboxSetField_Readonly; use SilverStripe\Forms\SearchableMultiDropdownField; use SilverStripe\Forms\SearchableDropdownField; +use PHPUnit\Framework\Attributes\DataProvider; class FormFieldTest extends SapphireTest { @@ -228,7 +229,7 @@ public function testAttributesHTML() /** * Covering all potential inputs for Convert::raw2xml */ - public function escapeHtmlDataProvider() + public static function escapeHtmlDataProvider() { return [ [''], @@ -238,8 +239,8 @@ public function escapeHtmlDataProvider() } /** - * @dataProvider escapeHtmlDataProvider **/ + #[DataProvider('escapeHtmlDataProvider')] public function testGetAttributesEscapeHtml($value) { $key = bin2hex(random_bytes(4)); @@ -258,9 +259,7 @@ public function testGetAttributesEscapeHtml($value) $this->assertFalse(strpos($html ?? '', '')); } - /** - * @dataProvider escapeHtmlDataProvider - */ + #[DataProvider('escapeHtmlDataProvider')] public function testDebugEscapeHtml($value) { $field = new FormField('', '', ''); @@ -606,7 +605,7 @@ public function testValidationExtensionHooksAreCalledOnFormFieldSubclasses() ->getMock(); $mock->expects($invocationRule = $this->once()) ->method('extendValidationResult') - ->will($this->returnValue(true)); + ->willReturn(true); $isValid = $mock->validate(new RequiredFields()); $this->assertTrue($isValid, "$formFieldClass should be valid"); @@ -651,8 +650,8 @@ public function testLinkWithoutForm() /** * @param string $name * @param string $expected - * @dataProvider nameToLabelProvider */ + #[DataProvider('nameToLabelProvider')] public function testNameToLabel($name, $expected) { $this->assertSame($expected, FormField::name_to_label($name)); @@ -661,7 +660,7 @@ public function testNameToLabel($name, $expected) /** * @return array[] */ - public function nameToLabelProvider() + public static function nameToLabelProvider() { return [ ['TotalAmount', 'Total amount'], diff --git a/tests/php/Forms/FormScaffolderTest.php b/tests/php/Forms/FormScaffolderTest.php index 9116bc82de5..72e012c7ded 100644 --- a/tests/php/Forms/FormScaffolderTest.php +++ b/tests/php/Forms/FormScaffolderTest.php @@ -17,6 +17,7 @@ use SilverStripe\Forms\Tests\FormScaffolderTest\ParentChildJoin; use SilverStripe\Forms\Tests\FormScaffolderTest\Tag; use SilverStripe\Forms\TimeField; +use PHPUnit\Framework\Attributes\DataProvider; /** * Tests for DataObject FormField scaffolding @@ -171,7 +172,7 @@ public function testGetFormFields() $this->assertFalse($fields->hasTabSet(), 'getFrontEndFields() doesnt produce a TabSet by default'); } - public function provideScaffoldRelationFormFields() + public static function provideScaffoldRelationFormFields() { $scenarios = [ 'ignore no relations' => [ @@ -193,9 +194,7 @@ public function provideScaffoldRelationFormFields() return $scenarios; } - /** - * @dataProvider provideScaffoldRelationFormFields - */ + #[DataProvider('provideScaffoldRelationFormFields')] public function testScaffoldRelationFormFields(bool $includeInOwnTab, array $ignoreRelations) { $parent = $this->objFromFixture(ParentModel::class, 'parent1'); @@ -271,31 +270,29 @@ public function testScaffoldRestrictRelations(): void $this->assertSame(['Tags'], $fields->column('Name')); } - public function provideTabs(): array + public static function provideTabs(): array { return [ 'only main tab' => [ - 'tabs' => true, + 'tabbed' => true, 'mainTabOnly' => true, ], 'all tabs, all fields' => [ - 'tabs' => true, + 'tabbed' => true, 'mainTabOnly' => false, ], 'no tabs, no fields' => [ - 'tabs' => false, + 'tabbed' => false, 'mainTabOnly' => true, ], 'no tabs, all fields' => [ - 'tabs' => false, + 'tabbed' => false, 'mainTabOnly' => false, ], ]; } - /** - * @dataProvider provideTabs - */ + #[DataProvider('provideTabs')] public function testTabs(bool $tabbed, bool $mainTabOnly): void { $parent = $this->objFromFixture(ParentModel::class, 'parent1'); diff --git a/tests/php/Forms/FormSchemaTest.php b/tests/php/Forms/FormSchemaTest.php index c032f3a5372..ed78a8ef70c 100644 --- a/tests/php/Forms/FormSchemaTest.php +++ b/tests/php/Forms/FormSchemaTest.php @@ -16,6 +16,7 @@ use SilverStripe\Forms\PopoverField; use SilverStripe\Forms\FormField; use LogicException; +use PHPUnit\Framework\Attributes\DataProvider; class FormSchemaTest extends SapphireTest { @@ -41,9 +42,7 @@ public function testGetSchema() $this->assertEquals($expected, $schema); } - /** - * @dataProvider provideGetSchemaException - */ + #[DataProvider('provideGetSchemaException')] public function testGetSchemaException(string $field, bool $expectException): void { $fields = []; @@ -66,7 +65,7 @@ public function testGetSchemaException(string $field, bool $expectException): vo $formSchema->getSchema($form); } - public function provideGetSchemaException(): array + public static function provideGetSchemaException(): array { return [ [ diff --git a/tests/php/Forms/FormTest.php b/tests/php/Forms/FormTest.php index 8b97293443a..55c79798ec0 100644 --- a/tests/php/Forms/FormTest.php +++ b/tests/php/Forms/FormTest.php @@ -33,6 +33,7 @@ use SilverStripe\Security\SecurityToken; use SilverStripe\View\ArrayData; use SilverStripe\View\SSViewer; +use PHPUnit\Framework\Attributes\DataProvider; class FormTest extends FunctionalTest { @@ -68,7 +69,7 @@ protected function setUp(): void /** * @return array */ - public function boolDataProvider() + public static function boolDataProvider() { return [ [false], @@ -76,7 +77,7 @@ public function boolDataProvider() ]; } - public function formMessageDataProvider() + public static function formMessageDataProvider() { return [ [ @@ -100,40 +101,40 @@ public function formMessageDataProvider() ]; } - public function formMessageExceptionsDataProvider() + public static function formMessageExceptionsDataProvider() { return [ [ - 'message_1' => [ + 'message1' => [ 'val' => 'Just a string', 'type' => ValidationResult::TYPE_ERROR, 'cast' => ValidationResult::CAST_TEXT, ], - 'message_2' => [ + 'message2' => [ 'val' => 'This is a good message', 'type' => ValidationResult::TYPE_GOOD, 'cast' => ValidationResult::CAST_TEXT, ], ], [ - 'message_1' => [ + 'message1' => [ 'val' => 'This is a good message', 'type' => ValidationResult::TYPE_GOOD, 'cast' => ValidationResult::CAST_TEXT, ], - 'message_2' => [ + 'message2' => [ 'val' => 'HTML is the future of the web', 'type' => ValidationResult::TYPE_GOOD, 'cast' => ValidationResult::CAST_HTML, ], ], [ - 'message_1' => [ + 'message1' => [ 'val' => 'This is a good message', 'type' => ValidationResult::TYPE_GOOD, 'cast' => ValidationResult::CAST_TEXT, ], - 'message_2' => [ + 'message2' => [ 'val' => 'HTML is the future of the web', 'type' => ValidationResult::TYPE_GOOD, 'cast' => ValidationResult::CAST_HTML, @@ -732,7 +733,7 @@ public function testDisableSecurityTokenAcceptsSubmissionWithoutToken(): void ); } - public function provideFormsSet() + public static function provideFormsSet() { return [ 'with security token' => @@ -756,9 +757,7 @@ public function provideFormsSet() ]; } - /** - * @dataProvider provideFormsSet - */ + #[DataProvider('provideFormsSet')] public function testSubmitFormWithSpecifiedParameters( array $formData, ?int $statusCode, @@ -1097,9 +1096,7 @@ public function testFieldMessageEscapeHtml() ); } - /** - * @dataProvider formMessageDataProvider - */ + #[DataProvider('formMessageDataProvider')] public function testFieldMessageAppend($messages) { $form = $this->getStubForm(); @@ -1115,9 +1112,7 @@ public function testFieldMessageAppend($messages) } } - /** - * @dataProvider formMessageExceptionsDataProvider - */ + #[DataProvider('formMessageExceptionsDataProvider')] public function testFieldMessageAppendExceptions(array $message1, array $message2, bool $force = false) { $form = $this->getStubForm(); @@ -1166,9 +1161,9 @@ public function testGetExtraFields() } /** - * @dataProvider boolDataProvider * @param bool $allow */ + #[DataProvider('boolDataProvider')] public function testPasswordPostback($allow) { $form = $this->getStubForm(); diff --git a/tests/php/Forms/GridField/GridFieldAddNewButtonTest.php b/tests/php/Forms/GridField/GridFieldAddNewButtonTest.php index 900c490e27e..f599012b01c 100644 --- a/tests/php/Forms/GridField/GridFieldAddNewButtonTest.php +++ b/tests/php/Forms/GridField/GridFieldAddNewButtonTest.php @@ -125,7 +125,7 @@ protected function mockButtonFragments(SS_List $list, $parent = null) protected function mockSingleton($class) { $mock = $this->getMockBuilder($class) - ->setMethods(['canCreate']) + ->onlyMethods(['canCreate']) ->getMock(); Injector::inst()->registerService($mock, $class); diff --git a/tests/php/Forms/GridField/GridFieldDataColumnsTest.php b/tests/php/Forms/GridField/GridFieldDataColumnsTest.php index b9e0c039796..8fc829dccd2 100644 --- a/tests/php/Forms/GridField/GridFieldDataColumnsTest.php +++ b/tests/php/Forms/GridField/GridFieldDataColumnsTest.php @@ -15,9 +15,6 @@ class GridFieldDataColumnsTest extends SapphireTest { - /** - * @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::getDisplayFields - */ public function testGridFieldGetDefaultDisplayFields() { $obj = new GridField('testfield', 'testfield', Member::get()); @@ -26,9 +23,6 @@ public function testGridFieldGetDefaultDisplayFields() $this->assertEquals($expected, $columns->getDisplayFields($obj)); } - /** - * @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::getDisplayFields - */ public function testGridFieldGetDisplayFieldsWithArrayList() { $list = new ArrayList([new ArrayData(['Title' => 'My Item'])]); @@ -39,10 +33,6 @@ public function testGridFieldGetDisplayFieldsWithArrayList() $this->assertEquals($expected, $columns->getDisplayFields($obj)); } - /** - * @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::setDisplayFields - * @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::getDisplayFields - */ public function testGridFieldCustomDisplayFields() { $obj = new GridField('testfield', 'testfield', Member::get()); @@ -52,10 +42,6 @@ public function testGridFieldCustomDisplayFields() $this->assertEquals($expected, $columns->getDisplayFields($obj)); } - /** - * @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::setDisplayFields - * @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::getDisplayFields - */ public function testGridFieldDisplayFieldsWithBadArguments() { $this->expectException(InvalidArgumentException::class); @@ -64,10 +50,6 @@ public function testGridFieldDisplayFieldsWithBadArguments() $columns->setDisplayFields(new stdClass()); } - /** - * @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::getFieldCasting - * @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::setFieldCasting - */ public function testFieldCasting() { $obj = new GridField('testfield', 'testfield'); @@ -77,10 +59,6 @@ public function testFieldCasting() $this->assertEquals(["MyShortText"=>"Text->FirstSentence"], $columns->getFieldCasting()); } - /** - * @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::getFieldFormatting - * @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::setFieldFormatting - */ public function testFieldFormatting() { $obj = new GridField('testfield', 'testfield'); diff --git a/tests/php/Forms/GridField/GridFieldDeleteActionTest.php b/tests/php/Forms/GridField/GridFieldDeleteActionTest.php index 8786d20bdad..8e28e65056c 100644 --- a/tests/php/Forms/GridField/GridFieldDeleteActionTest.php +++ b/tests/php/Forms/GridField/GridFieldDeleteActionTest.php @@ -26,6 +26,7 @@ use SilverStripe\Security\Security; use SilverStripe\Security\SecurityToken; use SilverStripe\View\ArrayData; +use PHPUnit\Framework\Attributes\DataProvider; class GridFieldDeleteActionTest extends SapphireTest { @@ -235,7 +236,7 @@ public function testMenuGroup() $this->assertNull($group, 'A menu group does not exist when the user cannot delete'); } - public function provideHandleActionThrowsException() + public static function provideHandleActionThrowsException() { return [ 'unlinks relation' => [true], @@ -243,9 +244,7 @@ public function provideHandleActionThrowsException() ]; } - /** - * @dataProvider provideHandleActionThrowsException - */ + #[DataProvider('provideHandleActionThrowsException')] public function testHandleActionThrowsException(bool $unlinkRelation) { $component = new GridFieldDeleteAction(); @@ -267,7 +266,7 @@ public function testHandleActionThrowsException(bool $unlinkRelation) $component->handleAction($gridField, $secondArg, ['RecordID' => 1], []); } - public function provideGetRemoveActionThrowsException() + public static function provideGetRemoveActionThrowsException() { return [ 'removes relation' => [true], @@ -275,9 +274,7 @@ public function provideGetRemoveActionThrowsException() ]; } - /** - * @dataProvider provideGetRemoveActionThrowsException - */ + #[DataProvider('provideGetRemoveActionThrowsException')] public function testGetRemoveActionThrowsException(bool $removeRelation) { $component = new GridFieldDeleteAction(); diff --git a/tests/php/Forms/GridField/GridFieldDetailFormTest.php b/tests/php/Forms/GridField/GridFieldDetailFormTest.php index 34c1848c1d9..eade6fb7f5f 100644 --- a/tests/php/Forms/GridField/GridFieldDetailFormTest.php +++ b/tests/php/Forms/GridField/GridFieldDetailFormTest.php @@ -26,6 +26,7 @@ use SilverStripe\Forms\Tests\GridField\GridFieldDetailFormTest\TestController; use SilverStripe\ORM\ArrayList; use SilverStripe\View\ArrayData; +use PHPUnit\Framework\Attributes\DataProvider; class GridFieldDetailFormTest extends FunctionalTest { @@ -496,7 +497,7 @@ public function testRedirectMissingRecords() $this->autoFollowRedirection = $origAutoFollow; } - public function provideGetRecordFromRequestFindExisting() + public static function provideGetRecordFromRequestFindExisting() { return [ 'No records' => [ @@ -518,9 +519,7 @@ public function provideGetRecordFromRequestFindExisting() ]; } - /** - * @dataProvider provideGetRecordFromRequestFindExisting - */ + #[DataProvider('provideGetRecordFromRequestFindExisting')] public function testGetRecordFromRequestFindExisting(array $data, bool $hasRecord) { $controller = new TestController(); @@ -538,7 +537,7 @@ public function testGetRecordFromRequestFindExisting(array $data, bool $hasRecor $this->assertSame($hasRecord, (bool) $reflectionMethod->invoke($component, $gridField, $request)); } - public function provideGetRecordFromRequestCreateNew() + public static function provideGetRecordFromRequestCreateNew() { // Note that in all of these scenarios a new record gets created, so it *shouldn't* matter what's already in there. return [ @@ -554,9 +553,7 @@ public function provideGetRecordFromRequestCreateNew() ]; } - /** - * @dataProvider provideGetRecordFromRequestCreateNew - */ + #[DataProvider('provideGetRecordFromRequestCreateNew')] public function testGetRecordFromRequestCreateNew(array $data) { $controller = new TestController(); @@ -574,7 +571,7 @@ public function testGetRecordFromRequestCreateNew(array $data) $this->assertEquals(new ArrayDataWithID(['ID' => 0]), $reflectionMethod->invoke($component, $gridField, $request)); } - public function provideGetRecordFromRequestWithoutData() + public static function provideGetRecordFromRequestWithoutData() { // Note that in all of these scenarios a new record gets created, so it *shouldn't* matter what's already in there. return [ @@ -590,9 +587,7 @@ public function provideGetRecordFromRequestWithoutData() ]; } - /** - * @dataProvider provideGetRecordFromRequestWithoutData - */ + #[DataProvider('provideGetRecordFromRequestWithoutData')] public function testGetRecordFromRequestWithoutData(array $data) { $controller = new TestController(); diff --git a/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php b/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php index 2a760c25ade..ad2365165ae 100644 --- a/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php +++ b/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php @@ -68,7 +68,6 @@ protected function setUp(): void /** * Tests that the appropriate filter headers are generated - * */ public function testRenderHeaders() { diff --git a/tests/php/Forms/GridField/GridFieldReadonlyTest.php b/tests/php/Forms/GridField/GridFieldReadonlyTest.php index 27b51096f4c..b377d337c5c 100644 --- a/tests/php/Forms/GridField/GridFieldReadonlyTest.php +++ b/tests/php/Forms/GridField/GridFieldReadonlyTest.php @@ -23,6 +23,7 @@ use SilverStripe\Forms\GridField\GridFieldViewButton; use SilverStripe\Forms\Tests\GridField\GridFieldReadonlyTest\GridFieldViewButtonReplacement; use SilverStripe\Versioned\VersionedGridFieldState\VersionedGridFieldState; +use PHPUnit\Framework\Attributes\DataProvider; class GridFieldReadonlyTest extends SapphireTest { @@ -33,7 +34,7 @@ class GridFieldReadonlyTest extends SapphireTest Cheerleader::class, ]; - public function provideReadOnlyTransformation(): array + public static function provideReadOnlyTransformation(): array { return [ [ @@ -51,9 +52,8 @@ public function provideReadOnlyTransformation(): array /** * The CMS can set the value of a GridField to be a hasMany relation, which needs a readonly state. * This test ensures GridField has a readonly transformation. - * - * @dataProvider provideReadOnlyTransformation */ + #[DataProvider('provideReadOnlyTransformation')] public function testReadOnlyTransformation(?string $viewButtonClass) { // Build a hasMany Relation via getComponents like ModelAdmin does. diff --git a/tests/php/Forms/GridField/GridFieldSortableHeaderTest.php b/tests/php/Forms/GridField/GridFieldSortableHeaderTest.php index 19315408ff2..6b2118454c5 100644 --- a/tests/php/Forms/GridField/GridFieldSortableHeaderTest.php +++ b/tests/php/Forms/GridField/GridFieldSortableHeaderTest.php @@ -31,7 +31,6 @@ class GridFieldSortableHeaderTest extends SapphireTest /** * Tests that the appropriate sortable headers are generated - * */ public function testRenderHeaders() { diff --git a/tests/php/Forms/GridField/GridFieldTest.php b/tests/php/Forms/GridField/GridFieldTest.php index 642460aa5ac..cf3f4d6f342 100644 --- a/tests/php/Forms/GridField/GridFieldTest.php +++ b/tests/php/Forms/GridField/GridFieldTest.php @@ -57,19 +57,12 @@ class GridFieldTest extends SapphireTest ], ]; - /** - * @covers \SilverStripe\Forms\GridField\GridField::__construct - */ public function testGridField() { $obj = new GridField('testfield', 'testfield'); $this->assertTrue($obj instanceof GridField, 'Test that the constructor arguments are valid'); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::__construct - * @covers \SilverStripe\Forms\GridField\GridField::getList - */ public function testGridFieldSetList() { $list = ArrayList::create([1 => 'hello', 2 => 'goodbye']); @@ -77,12 +70,6 @@ public function testGridFieldSetList() $this->assertEquals($list, $obj->getList(), 'Testing getList'); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::__construct - * @covers \SilverStripe\Forms\GridField\GridField::getConfig - * @covers \SilverStripe\Forms\GridField\GridFieldConfig_Base::__construct - * @covers \SilverStripe\Forms\GridField\GridFieldConfig::addComponent - */ public function testGridFieldDefaultConfig() { $obj = new GridField('testfield', 'testfield'); @@ -104,10 +91,6 @@ public function testGridFieldDefaultConfig() $this->assertEquals($expectedComponents, $obj->getConfig()->getComponents(), 'Testing default Config'); } - /** - * @covers \SilverStripe\Forms\GridField\GridFieldConfig::__construct - * @covers \SilverStripe\Forms\GridField\GridFieldConfig::addComponent - */ public function testGridFieldSetCustomConfig() { @@ -128,10 +111,6 @@ public function testGridFieldSetCustomConfig() $this->assertEquals($expectedComponents, $obj->getConfig()->getComponents(), 'Testing default Config'); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getModelClass - * @covers \SilverStripe\Forms\GridField\GridField::setModelClass - */ public function testGridFieldModelClass() { $obj = new GridField('testfield', 'testfield', Member::get()); @@ -140,9 +119,6 @@ public function testGridFieldModelClass() $this->assertEquals(Group::class, $obj->getModelClass(), 'Should return Group'); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getModelClass - */ public function testGridFieldModelClassThrowsException() { $this->expectException(LogicException::class); @@ -150,10 +126,6 @@ public function testGridFieldModelClassThrowsException() $obj->getModelClass(); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::setList - * @covers \SilverStripe\Forms\GridField\GridField::getList - */ public function testSetAndGetList() { $list = Member::get(); @@ -164,9 +136,6 @@ public function testSetAndGetList() $this->assertEquals($arrayList, $obj->getList()); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getState - */ public function testGetState() { $obj = new GridField('testfield', 'testfield'); @@ -176,10 +145,6 @@ public function testGetState() /** * Tests usage of nested GridState values - * - * @covers \SilverStripe\Forms\GridField\GridState_Data::__get - * @covers \SilverStripe\Forms\GridField\GridState_Data::__call - * @covers \SilverStripe\Forms\GridField\GridState_Data::getData */ public function testGetStateData() { @@ -220,9 +185,6 @@ public function testGetStateData() $this->assertEquals(10, $obj->State->Nested->DeeperNested->DataValue(10)); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getColumns - */ public function testGetColumns() { $obj = new GridField('testfield', 'testfield', Member::get()); @@ -234,18 +196,12 @@ public function testGetColumns() $this->assertEquals($expected, $obj->getColumns()); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getColumnCount - */ public function testGetColumnCount() { $obj = new GridField('testfield', 'testfield', Member::get()); $this->assertEquals(3, $obj->getColumnCount()); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getColumnContent - */ public function testGetColumnContent() { $list = new ArrayList( @@ -257,9 +213,6 @@ public function testGetColumnContent() $this->assertEquals('test@example.org', $obj->getColumnContent($list->first(), 'Email')); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getColumnContent - */ public function testGetColumnContentBadArguments() { $this->expectException(InvalidArgumentException::class); @@ -272,9 +225,6 @@ public function testGetColumnContentBadArguments() $obj->getColumnContent($list->first(), 'non-existing'); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getColumnAttributes - */ public function testGetColumnAttributesEmptyArray() { $list = new ArrayList( @@ -286,9 +236,6 @@ public function testGetColumnAttributesEmptyArray() $this->assertEquals(['class' => 'col-Email'], $obj->getColumnAttributes($list->first(), 'Email')); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getColumnAttributes - */ public function testGetColumnAttributes() { $list = new ArrayList( @@ -301,9 +248,6 @@ public function testGetColumnAttributes() $this->assertEquals(['class' => 'css-class'], $obj->getColumnAttributes($list->first(), 'Email')); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getColumnAttributes - */ public function testGetColumnAttributesBadArguments() { $this->expectException(\InvalidArgumentException::class); @@ -330,9 +274,6 @@ public function testGetColumnAttributesBadResponseFromComponent() $obj->getColumnAttributes($list->first(), 'Surname'); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getColumnMetadata - */ public function testGetColumnMetadata() { $list = new ArrayList( @@ -345,9 +286,6 @@ public function testGetColumnMetadata() $this->assertEquals(['metadata' => 'istrue'], $obj->getColumnMetadata('Email')); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getColumnMetadata - */ public function testGetColumnMetadataBadResponseFromComponent() { $this->expectException(\LogicException::class); @@ -361,9 +299,6 @@ public function testGetColumnMetadataBadResponseFromComponent() $obj->getColumnMetadata('Surname'); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getColumnMetadata - */ public function testGetColumnMetadataBadArguments() { $this->expectException(\InvalidArgumentException::class); @@ -373,9 +308,6 @@ public function testGetColumnMetadataBadArguments() $obj->getColumnMetadata('non-exist-qweqweqwe'); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::handleAction - */ public function testHandleActionBadArgument() { $this->expectException(\InvalidArgumentException::class); @@ -383,9 +315,6 @@ public function testHandleActionBadArgument() $obj->handleAlterAction('prft', [], []); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::handleAction - */ public function testHandleAction() { $config = GridFieldConfig::create()->addComponent(new Component); @@ -393,9 +322,6 @@ public function testHandleAction() $this->assertEquals('handledAction is executed', $obj->handleAlterAction('jump', [], [])); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getCastedValue - */ public function testGetCastedValue() { $obj = new GridField('testfield', 'testfield'); @@ -403,9 +329,6 @@ public function testGetCastedValue() $this->assertEquals('This is a sentence.', $value); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::getCastedValue - */ public function testGetCastedValueObject() { $obj = new GridField('testfield', 'testfield'); @@ -413,9 +336,6 @@ public function testGetCastedValueObject() $this->assertEquals('Here is some <html> content', $value); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::gridFieldAlterAction - */ public function testGridFieldAlterAction() { $this->markTestIncomplete(); @@ -547,9 +467,6 @@ public function testGridFieldCustomFragmentsCircularDependencyThrowsException() $field->FieldHolder(); } - /** - * @covers \SilverStripe\Forms\GridField\GridField::FieldHolder - */ public function testCanViewOnlyOddIDs() { $this->logInWithPermission(); diff --git a/tests/php/Forms/HTMLEditor/HTMLEditorFieldTest.php b/tests/php/Forms/HTMLEditor/HTMLEditorFieldTest.php index f17b1fe124e..d9f69cfe49c 100644 --- a/tests/php/Forms/HTMLEditor/HTMLEditorFieldTest.php +++ b/tests/php/Forms/HTMLEditor/HTMLEditorFieldTest.php @@ -18,6 +18,7 @@ use SilverStripe\Forms\HTMLReadonlyField; use SilverStripe\Forms\Tests\HTMLEditor\HTMLEditorFieldTest\TestObject; use SilverStripe\ORM\FieldType\DBHTMLText; +use PHPUnit\Framework\Attributes\DataProvider; class HTMLEditorFieldTest extends FunctionalTest { @@ -215,7 +216,7 @@ public function testReadonlyField() ); } - public function provideTestValueEntities() + public static function provideTestValueEntities() { return [ "ampersand" => [ @@ -233,9 +234,7 @@ public function provideTestValueEntities() ]; } - /** - * @dataProvider provideTestValueEntities - */ + #[DataProvider('provideTestValueEntities')] public function testValueEntities(string $input, string $result) { $field = new HTMLEditorField("Content"); diff --git a/tests/php/Forms/HTMLEditor/HTMLEditorSanitiserTest.php b/tests/php/Forms/HTMLEditor/HTMLEditorSanitiserTest.php index ee3d9980212..59d216c46aa 100644 --- a/tests/php/Forms/HTMLEditor/HTMLEditorSanitiserTest.php +++ b/tests/php/Forms/HTMLEditor/HTMLEditorSanitiserTest.php @@ -7,11 +7,12 @@ use SilverStripe\Forms\HTMLEditor\HTMLEditorConfig; use SilverStripe\Forms\HTMLEditor\HTMLEditorSanitiser; use SilverStripe\View\Parsers\HTMLValue; +use PHPUnit\Framework\Attributes\DataProvider; class HTMLEditorSanitiserTest extends FunctionalTest { - public function provideSanitise(): array + public static function provideSanitise(): array { return [ [ @@ -155,9 +156,7 @@ public function provideSanitise(): array ]; } - /** - * @dataProvider provideSanitise - */ + #[DataProvider('provideSanitise')] public function testSanitisation(string $validElements, string $input, string $output, string $desc): void { foreach (['valid_elements', 'extended_valid_elements'] as $configType) { diff --git a/tests/php/Forms/NumericFieldTest.php b/tests/php/Forms/NumericFieldTest.php index ca6a08af74a..2b52db3351d 100644 --- a/tests/php/Forms/NumericFieldTest.php +++ b/tests/php/Forms/NumericFieldTest.php @@ -6,6 +6,7 @@ use SilverStripe\Forms\NumericField; use SilverStripe\Forms\RequiredFields; use SilverStripe\i18n\i18n; +use PHPUnit\Framework\Attributes\DataProvider; class NumericFieldTest extends SapphireTest { @@ -15,12 +16,12 @@ class NumericFieldTest extends SapphireTest * Test that data loaded in via Form::loadDataFrom(DataObject) will populate the field correctly, * and can format the database value appropriately for the frontend * - * @dataProvider dataForTestSetValue * @param string $locale Locale to test in * @param int $scale Scale size (number of decimal places) * @param string $input Input string * @param int|float $output Expected data value */ + #[DataProvider('dataForTestSetValue')] public function testSetValue($locale, $scale, $input, $output) { $field = new NumericField('Number'); @@ -55,7 +56,7 @@ public function testSetValue($locale, $scale, $input, $output) /** * Test formatting of numbers */ - public function dataForTestSetValue() + public static function dataForTestSetValue() { return [ // de @@ -124,7 +125,7 @@ public function testNullSet() $this->assertEquals(0, $field->dataValue()); } - public function dataForTestSubmittedValue() + public static function dataForTestSubmittedValue() { return [ ['de_DE', 0, '13000', 13000, '13.000'], @@ -187,13 +188,13 @@ public function dataForTestSubmittedValue() } /** - * @dataProvider dataForTestSubmittedValue * @param string $locale Locale to test in * @param int $scale Scale size (number of decimal places) * @param string $submittedValue Input string * @param int|float $dataValue Expected data value * @param string $cleanedInput */ + #[DataProvider('dataForTestSubmittedValue')] public function testSetSubmittedValue($locale, $scale, $submittedValue, $dataValue, $cleanedInput = null) { $field = new NumericField('Number'); diff --git a/tests/php/Forms/PasswordFieldTest.php b/tests/php/Forms/PasswordFieldTest.php index 4dfb4a38c89..90230d89759 100644 --- a/tests/php/Forms/PasswordFieldTest.php +++ b/tests/php/Forms/PasswordFieldTest.php @@ -5,10 +5,11 @@ use SilverStripe\Core\Config\Config; use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\PasswordField; +use PHPUnit\Framework\Attributes\DataProvider; class PasswordFieldTest extends SapphireTest { - public function boolDataProvider() + public static function boolDataProvider() { return [ [false], @@ -17,9 +18,9 @@ public function boolDataProvider() } /** - * @dataProvider boolDataProvider * @param bool $bool */ + #[DataProvider('boolDataProvider')] public function testAutocomplete($bool) { Config::modify()->set(PasswordField::class, 'autocomplete', $bool); @@ -31,9 +32,9 @@ public function testAutocomplete($bool) } /** - * @dataProvider boolDataProvider * @param bool $bool */ + #[DataProvider('boolDataProvider')] public function testValuePostback($bool) { $field = (new PasswordField('test', 'test', 'password')) diff --git a/tests/php/Forms/RequiredFieldsTest.php b/tests/php/Forms/RequiredFieldsTest.php index 5c080cfc9f9..3ee6e8d2732 100644 --- a/tests/php/Forms/RequiredFieldsTest.php +++ b/tests/php/Forms/RequiredFieldsTest.php @@ -8,6 +8,7 @@ use SilverStripe\Forms\SearchableDropdownField; use SilverStripe\Forms\TreeDropdownField; use SilverStripe\Security\Group; +use PHPUnit\Framework\Attributes\DataProvider; class RequiredFieldsTest extends SapphireTest { @@ -290,7 +291,7 @@ public function testFieldIsRequired() ); } - public function provideHasOneRelationFieldInterfaceValidation(): array + public static function provideHasOneRelationFieldInterfaceValidation(): array { return [ [ @@ -302,9 +303,7 @@ public function provideHasOneRelationFieldInterfaceValidation(): array ]; } - /** - * @dataProvider provideHasOneRelationFieldInterfaceValidation - */ + #[DataProvider('provideHasOneRelationFieldInterfaceValidation')] public function testHasOneRelationFieldInterfaceValidation(string $className) { $form = new Form(); diff --git a/tests/php/Forms/SearchableDropdownTraitTest.php b/tests/php/Forms/SearchableDropdownTraitTest.php index d3796cfa239..c20f4f81d81 100644 --- a/tests/php/Forms/SearchableDropdownTraitTest.php +++ b/tests/php/Forms/SearchableDropdownTraitTest.php @@ -15,6 +15,7 @@ use SilverStripe\Forms\HiddenField; use stdClass; use SilverStripe\Forms\Form; +use PHPUnit\Framework\Attributes\DataProvider; class SearchableDropdownTraitTest extends SapphireTest { @@ -103,9 +104,7 @@ public function testLabelField(): void $this->assertSame('Something', $field->getLabelField()); } - /** - * @dataProvider provideGetValueArray - */ + #[DataProvider('provideGetValueArray')] public function testGetValueArray(mixed $value, string|array $expected): void { if ($value === '') { @@ -121,7 +120,7 @@ public function testGetValueArray(mixed $value, string|array $expected): void $this->assertSame($expected, $field->getValueArray()); } - public function provideGetValueArray(): array + public static function provideGetValueArray(): array { return [ 'empty' => [ @@ -219,7 +218,7 @@ public function testGetSchemaDataDefaults(): void $this->assertFalse($schema['searchable']); } - public function provideLazyLoadedDoesntCallGetSource() + public static function provideLazyLoadedDoesntCallGetSource() { $methodsToCall = [ 'Field', @@ -244,9 +243,7 @@ public function provideLazyLoadedDoesntCallGetSource() return $scenarios; } - /** - * @dataProvider provideLazyLoadedDoesntCallGetSource - */ + #[DataProvider('provideLazyLoadedDoesntCallGetSource')] public function testLazyLoadedDoesntCallGetSource(string $fieldClass, string $methodToCall) { // Some methods aren't shared between the two form fields. diff --git a/tests/php/Forms/UrlFieldTest.php b/tests/php/Forms/UrlFieldTest.php index 72cd2efb4d1..077a85e79dc 100644 --- a/tests/php/Forms/UrlFieldTest.php +++ b/tests/php/Forms/UrlFieldTest.php @@ -5,10 +5,11 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\UrlField; use SilverStripe\Forms\RequiredFields; +use PHPUnit\Framework\Attributes\DataProvider; class UrlFieldTest extends SapphireTest { - public function provideValidate(): array + public static function provideValidate(): array { return [ [ @@ -78,13 +79,11 @@ public function provideValidate(): array ]; } - /** - * @dataProvider provideValidate - */ - public function testValidate(string $email, bool $valid) + #[DataProvider('provideValidate')] + public function testValidate(string $url, bool $valid) { $field = new UrlField('MyUrl'); - $field->setValue($email); + $field->setValue($url); $validator = new RequiredFields(); $field->validate($validator); $expectedCount = $valid ? 0 : 1; diff --git a/tests/php/Logging/DebugViewFriendlyErrorFormatterTest.php b/tests/php/Logging/DebugViewFriendlyErrorFormatterTest.php index 2a730e56b08..42aa30bebf0 100644 --- a/tests/php/Logging/DebugViewFriendlyErrorFormatterTest.php +++ b/tests/php/Logging/DebugViewFriendlyErrorFormatterTest.php @@ -21,7 +21,7 @@ public function testFormatPassesRecordCodeToOutput() { /** @var DebugViewFriendlyErrorFormatter|MockObject $mock */ $mock = $this->getMockBuilder(DebugViewFriendlyErrorFormatter::class) - ->setMethods(['output']) + ->onlyMethods(['output']) ->getMock(); $mock->expects($this->once())->method('output')->with(403)->willReturn('foo'); @@ -32,7 +32,7 @@ public function testFormatPassesInstanceStatusCodeToOutputWhenNotProvidedByRecor { /** @var DebugViewFriendlyErrorFormatter|MockObject $mock */ $mock = $this->getMockBuilder(DebugViewFriendlyErrorFormatter::class) - ->setMethods(['output']) + ->onlyMethods(['output']) ->getMock(); $mock->setStatusCode(404); @@ -51,7 +51,7 @@ public function testFormatBatch() /** @var DebugViewFriendlyErrorFormatter|MockObject $mock */ $mock = $this->getMockBuilder(DebugViewFriendlyErrorFormatter::class) - ->setMethods(['format']) + ->onlyMethods(['format']) ->getMock(); $mock->expects($this->exactly(3)) diff --git a/tests/php/Logging/HTTPOutputHandlerTest.php b/tests/php/Logging/HTTPOutputHandlerTest.php index 065d0794c56..dc43867b8bc 100644 --- a/tests/php/Logging/HTTPOutputHandlerTest.php +++ b/tests/php/Logging/HTTPOutputHandlerTest.php @@ -13,6 +13,7 @@ use SilverStripe\Logging\DebugViewFriendlyErrorFormatter; use SilverStripe\Logging\DetailedErrorFormatter; use SilverStripe\Logging\HTTPOutputHandler; +use PHPUnit\Framework\Attributes\DataProvider; class HTTPOutputHandlerTest extends SapphireTest { @@ -58,7 +59,7 @@ public function testDevConfig() $this->assertInstanceOf(DetailedErrorFormatter::class, $handler->getFormatter()); } - public function provideShouldShowError() + public static function provideShouldShowError() { $provide = []; // See https://www.php.net/manual/en/errorfunc.constants.php @@ -145,9 +146,7 @@ public function provideShouldShowError() return $provide; } - /** - * @dataProvider provideShouldShowError - */ + #[DataProvider('provideShouldShowError')] public function testShouldShowError( int $errorCode, bool $triggeringError, diff --git a/tests/php/ORM/ArrayLibTest.php b/tests/php/ORM/ArrayLibTest.php index 39615f31603..c8732e35ed1 100644 --- a/tests/php/ORM/ArrayLibTest.php +++ b/tests/php/ORM/ArrayLibTest.php @@ -5,10 +5,10 @@ use PHPUnit\Framework\ExpectationFailedException; use SilverStripe\ORM\ArrayLib; use SilverStripe\Dev\SapphireTest; +use PHPUnit\Framework\Attributes\DataProvider; class ArrayLibTest extends SapphireTest { - public function testInvert() { $arr = [ @@ -369,7 +369,7 @@ public function testShuffleAssociative() } } - public function provideInsertBefore(): array + public static function provideInsertBefore(): array { return [ 'simple insertion' => [ @@ -445,9 +445,7 @@ public function provideInsertBefore(): array ]; } - /** - * @dataProvider provideInsertBefore - */ + #[DataProvider('provideInsertBefore')] public function testInsertBefore(mixed $insert, mixed $before, bool $strict, bool $splat, array $expected): void { $array = ['abc', '', [1,2,3], 'def', '0', null, true, 0, 'last']; @@ -455,75 +453,75 @@ public function testInsertBefore(mixed $insert, mixed $before, bool $strict, boo $this->assertSame($expected, $final); } - public function provideInsertAfter(): array + public static function provideInsertAfter(): array { return [ 'simple insertion' => [ 'insert' => 'new', - 'before' => 'def', + 'after' => 'def', 'strict' => true, 'splat' => false, 'expected' => ['abc', '', [1,2,3], 'def', 'new', '0', null, true, 0, 'last'] ], 'insert after first' => [ 'insert' => 'new', - 'before' => 'abc', + 'after' => 'abc', 'strict' => true, 'splat' => false, 'expected' => ['abc', 'new', '', [1,2,3], 'def', '0', null, true, 0, 'last'] ], 'insert after last' => [ 'insert' => 'new', - 'before' => 'last', + 'after' => 'last', 'strict' => true, 'splat' => false, 'expected' => ['abc', '', [1,2,3], 'def', '0', null, true, 0, 'last', 'new'] ], 'insert after missing' => [ 'insert' => 'new', - 'before' => 'this value isnt there', + 'after' => 'this value isnt there', 'strict' => true, 'splat' => false, 'expected' => ['abc', '', [1,2,3], 'def', '0', null, true, 0, 'last', 'new'] ], 'strict' => [ 'insert' => 'new', - 'before' => 0, + 'after' => 0, 'strict' => true, 'splat' => false, 'expected' => ['abc', '', [1,2,3], 'def', '0', null, true, 0, 'new', 'last'] ], 'not strict' => [ 'insert' => 'new', - 'before' => 0, + 'after' => 0, 'strict' => false, 'splat' => false, 'expected' => ['abc', '', [1,2,3], 'def', '0', 'new', null, true, 0, 'last'] ], 'after array' => [ 'insert' => 'new', - 'before' => [1,2,3], + 'after' => [1,2,3], 'strict' => true, 'splat' => false, 'expected' => ['abc', '', [1,2,3], 'new', 'def', '0', null, true, 0, 'last'] ], 'after missing array' => [ 'insert' => 'new', - 'before' => ['a', 'b', 'c'], + 'after' => ['a', 'b', 'c'], 'strict' => true, 'splat' => false, 'expected' => ['abc', '', [1,2,3], 'def', '0', null, true, 0, 'last', 'new'] ], 'splat array' => [ 'insert' => ['a', 'b', 'c'], - 'before' => 'def', + 'after' => 'def', 'strict' => true, 'splat' => true, 'expected' => ['abc', '', [1,2,3], 'def', 'a', 'b', 'c', '0', null, true, 0, 'last'] ], 'no splat array' => [ 'insert' => ['a', 'b', 'c'], - 'before' => 'def', + 'after' => 'def', 'strict' => true, 'splat' => false, 'expected' => ['abc', '', [1,2,3], 'def', ['a', 'b', 'c'], '0', null, true, 0, 'last'] @@ -531,9 +529,7 @@ public function provideInsertAfter(): array ]; } - /** - * @dataProvider provideInsertAfter - */ + #[DataProvider('provideInsertAfter')] public function testInsertAfter(mixed $insert, mixed $after, bool $strict, bool $splat, array $expected): void { $array = ['abc', '', [1,2,3], 'def', '0', null, true, 0, 'last']; diff --git a/tests/php/ORM/ArrayListTest.php b/tests/php/ORM/ArrayListTest.php index 235222da31c..bc16b302288 100644 --- a/tests/php/ORM/ArrayListTest.php +++ b/tests/php/ORM/ArrayListTest.php @@ -8,6 +8,7 @@ use SilverStripe\ORM\Filterable; use SilverStripe\View\ArrayData; use stdClass; +use PHPUnit\Framework\Attributes\DataProvider; class ArrayListTest extends SapphireTest { @@ -118,7 +119,7 @@ function ($item) use (&$count, $test) { $this->assertEquals($list->Count(), $count); } - public function limitDataProvider(): array + public static function limitDataProvider(): array { $all = [ ['Key' => 1], ['Key' => 2], ['Key' => 3] ]; list($one, $two, $three) = $all; @@ -141,9 +142,7 @@ public function limitDataProvider(): array ]; } - /** - * @dataProvider limitDataProvider - */ + #[DataProvider('limitDataProvider')] public function testLimit($length, $offset, array $expected) { $data = [ @@ -343,9 +342,9 @@ public function testMap() ); } - public function provideFindWithSearchfilters() + public static function provideFindWithSearchfilters() { - $objects = $this->getFilterWithSearchfiltersObjects(); + $objects = ArrayListTest::getFilterWithSearchfiltersObjects(); return [ // test a couple of search filters // don't need to be as explicit as the filter tests, just check the syntax works @@ -387,9 +386,7 @@ public function provideFindWithSearchfilters() ]; } - /** - * @dataProvider provideFindWithSearchfilters - */ + #[DataProvider('provideFindWithSearchfilters')] public function testFindWithSearchfilters(array $args, array $objects, object|array|null $expected) { $list = new ArrayList($objects); @@ -970,21 +967,19 @@ public function testMultipleWithArrayFilterAdvanced() $this->assertEquals($expected, $list->toArray(), 'List should only contain Steve and Steve and Clair'); } - /** - * @dataProvider provideFilterNullComparisons - */ - public function testFilterNullComparisons(mixed $objectValue, mixed $filterValue, bool $doesMatch, bool $negated = false) + #[DataProvider('provideFilterNullComparisons')] + public function testFilterNullComparisons(mixed $objectValue, mixed $filterValues, bool $doesMatch, bool $negated = false) { $filterField = 'Value'; if ($negated) { $filterField .= ':not'; } $list = new ArrayList([['Value' => $objectValue]]); - $list = $list->filter($filterField, $filterValue); + $list = $list->filter($filterField, $filterValues); $this->assertCount($doesMatch ? 1 : 0, $list); } - public function provideFilterNullComparisons() + public static function provideFilterNullComparisons() { // This is for backwards compatibility, since arraylist used to just do a straight == comparison // Everything that passes here would have passed a $objectValue == $filterValue comparison previously @@ -1091,7 +1086,7 @@ public function provideFilterNullComparisons() return $scenarios; } - private function getFilterWithSearchfiltersObjects() + private static function getFilterWithSearchfiltersObjects() { return [ [ @@ -1149,12 +1144,12 @@ private function getFilterWithSearchfiltersObjects() ]; } - public function provideFilterWithSearchfilters() + public static function provideFilterWithSearchfilters() { // Note that search filter tests here are to test syntax and to ensure all supported search filters // work with arraylist - but we don't need to test every possible edge case here, // we can rely on individual searchfilter unit tests for many edge cases - $objects = $this->getFilterWithSearchfiltersObjects(); + $objects = ArrayListTest::getFilterWithSearchfiltersObjects(); return [ // exact match filter tests 'exact match - negate' => [ @@ -1171,7 +1166,7 @@ public function provideFilterWithSearchfilters() 'expected' => [$objects[1], $objects[3], $objects[4]], ], 'exact match negated - nothing gets filtered out' => [ - 'filter' => ['Title:not', 'No object has this title - we should have all objects'], + 'args' => ['Title:not', 'No object has this title - we should have all objects'], 'objects' => $objects, 'expected' => $objects, ], @@ -1311,9 +1306,7 @@ public function provideFilterWithSearchfilters() ]; } - /** - * @dataProvider provideFilterWithSearchfilters - */ + #[DataProvider('provideFilterWithSearchfilters')] public function testFilterWithSearchfilters(array $args, array $objects, array $expected) { $list = new ArrayList($objects); @@ -1321,9 +1314,9 @@ public function testFilterWithSearchfilters(array $args, array $objects, array $ $this->assertEquals(array_column($expected, 'ID'), $list->column('ID')); } - public function provideFilterAnyWithSearchfilters() + public static function provideFilterAnyWithSearchfilters() { - $objects = $this->getFilterWithSearchfiltersObjects(); + $objects = ArrayListTest::getFilterWithSearchfiltersObjects(); return [ // test a couple of search filters // don't need to be as explicit as the filter tests, just check the syntax works @@ -1368,9 +1361,7 @@ public function provideFilterAnyWithSearchfilters() ]; } - /** - * @dataProvider provideFilterAnyWithSearchfilters - */ + #[DataProvider('provideFilterAnyWithSearchfilters')] public function testFilterAnyWithSearchfilters(array $args, array $objects, array $expected) { $list = new ArrayList($objects); @@ -1378,7 +1369,7 @@ public function testFilterAnyWithSearchfilters(array $args, array $objects, arra $this->assertEquals(array_column($expected, 'ID'), $list->column('ID')); } - public function provideFilterAny() + public static function provideFilterAny() { $list = new ArrayList( [ @@ -1429,9 +1420,7 @@ public function provideFilterAny() ]; } - /** - * @dataProvider provideFilterAny - */ + #[DataProvider('provideFilterAny')] public function testFilterAny(ArrayList $list, array $args, array $contains) { $filteredList = $list->filterAny(...$args)->toArray(); @@ -1650,12 +1639,12 @@ public function testMultipleExcludeThreeArguments() $this->assertEquals($expected, $list->toArray()); } - public function provideExcludeWithSearchfilters() + public static function provideExcludeWithSearchfilters() { // If it's included in the filter test, then it's excluded in the exclude test, // so we can just use the same scenarios and reverse the expected results. - $objects = $this->getFilterWithSearchfiltersObjects(); - $scenarios = $this->provideFilterWithSearchfilters(); + $objects = ArrayListTest::getFilterWithSearchfiltersObjects(); + $scenarios = ArrayListTest::provideFilterWithSearchfilters(); foreach ($scenarios as $name => $scenario) { $kept = []; $excluded = []; @@ -1672,9 +1661,7 @@ public function provideExcludeWithSearchfilters() return $scenarios; } - /** - * @dataProvider provideExcludeWithSearchfilters - */ + #[DataProvider('provideExcludeWithSearchfilters')] public function testExcludeWithSearchfilters(array $args, array $objects, array $expected) { $list = new ArrayList($objects); @@ -1682,12 +1669,12 @@ public function testExcludeWithSearchfilters(array $args, array $objects, array $this->assertEquals($expected, $list->toArray()); } - public function provideExcludeAnyWithSearchfilters() + public static function provideExcludeAnyWithSearchfilters() { // If it's included in the filterAny test, then it's excluded in the excludeAny test, // so we can just use the same scenarios and reverse the expected results. - $objects = $this->getFilterWithSearchfiltersObjects(); - $scenarios = $this->provideFilterAnyWithSearchfilters(); + $objects = ArrayListTest::getFilterWithSearchfiltersObjects(); + $scenarios = ArrayListTest::provideFilterAnyWithSearchfilters(); foreach ($scenarios as $name => $scenario) { $kept = []; $excluded = []; @@ -1704,9 +1691,7 @@ public function provideExcludeAnyWithSearchfilters() return $scenarios; } - /** - * @dataProvider provideExcludeAnyWithSearchfilters - */ + #[DataProvider('provideExcludeAnyWithSearchfilters')] public function testExcludeAnyWithSearchfilters(array $args, array $objects, array $expected) { $list = new ArrayList($objects); @@ -1714,11 +1699,11 @@ public function testExcludeAnyWithSearchfilters(array $args, array $objects, arr $this->assertEquals($expected, $list->toArray()); } - public function provideExcludeAny() + public static function provideExcludeAny() { // If it's included in the filterAny test, then it's excluded in the excludeAny test, // so we can just use the same scenarios and reverse the expected results. - $scenarios = $this->provideFilterAny(); + $scenarios = ArrayListTest::provideFilterAny(); foreach ($scenarios as $name => $scenario) { $kept = []; $excluded = []; @@ -1738,9 +1723,7 @@ public function provideExcludeAny() return $scenarios; } - /** - * @dataProvider provideExcludeAny - */ + #[DataProvider('provideExcludeAny')] public function testExcludeAny(ArrayList $list, array $args, array $contains) { $filteredList = $list->excludeAny(...$args)->toArray(); diff --git a/tests/php/ORM/Connect/DBQueryBuilderTest.php b/tests/php/ORM/Connect/DBQueryBuilderTest.php index 20645c40f01..88a41633982 100644 --- a/tests/php/ORM/Connect/DBQueryBuilderTest.php +++ b/tests/php/ORM/Connect/DBQueryBuilderTest.php @@ -6,12 +6,13 @@ use SilverStripe\Core\Environment; use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\Connect\DBQueryBuilder; +use PHPUnit\Framework\Attributes\DataProvider; class DBQueryBuilderTest extends SapphireTest { protected $usesDatabase = false; - public function provideShouldBuildTraceComment(): array + public static function provideShouldBuildTraceComment(): array { return [ [ @@ -47,9 +48,7 @@ public function provideShouldBuildTraceComment(): array ]; } - /** - * @dataProvider provideShouldBuildTraceComment - */ + #[DataProvider('provideShouldBuildTraceComment')] public function testShouldBuildTraceComment(?bool $envValue, bool $yamlValue, bool $expected): void { $queryBuilder = new DBQueryBuilder(); diff --git a/tests/php/ORM/DBDateTest.php b/tests/php/ORM/DBDateTest.php index d91360155cc..b9ba551d4ab 100644 --- a/tests/php/ORM/DBDateTest.php +++ b/tests/php/ORM/DBDateTest.php @@ -9,6 +9,7 @@ use SilverStripe\ORM\FieldType\DBDate; use SilverStripe\ORM\FieldType\DBDatetime; use SilverStripe\ORM\FieldType\DBField; +use PHPUnit\Framework\Attributes\DataProvider; class DBDateTest extends SapphireTest { @@ -349,8 +350,8 @@ public function testRfc3999() /** * @param string $adjustment * @param string $expected - * @dataProvider modifyProvider */ + #[DataProvider('modifyProvider')] public function testModify($adjustment, $expected) { /** @var DBDate $dateField */ @@ -362,7 +363,7 @@ public function testModify($adjustment, $expected) /** * @return array[] */ - public function modifyProvider() + public static function modifyProvider() { return [ ['+1 day', '2019-03-04'], diff --git a/tests/php/ORM/DBDatetimeTest.php b/tests/php/ORM/DBDatetimeTest.php index 9196016d814..6441d18c547 100644 --- a/tests/php/ORM/DBDatetimeTest.php +++ b/tests/php/ORM/DBDatetimeTest.php @@ -5,6 +5,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\i18n\i18n; use SilverStripe\ORM\FieldType\DBDatetime; +use PHPUnit\Framework\Attributes\DataProvider; /** * Tests for {@link Datetime} class. @@ -271,8 +272,8 @@ public function testRfc3999() /** * @param string $adjustment * @param string $expected - * @dataProvider modifyProvider */ + #[DataProvider('modifyProvider')] public function testModify($adjustment, $expected) { DBDatetime::set_mock_now('2019-03-03 12:00:00'); @@ -283,7 +284,7 @@ public function testModify($adjustment, $expected) /** * @return array[] */ - public function modifyProvider() + public static function modifyProvider() { return [ ['+1 day', '2019-03-04 12:00:00'], @@ -303,7 +304,7 @@ public function modifyProvider() ]; } - public function provideGetTimeBetween(): array + public static function provideGetTimeBetween(): array { return [ 'no time between' => [ @@ -339,9 +340,7 @@ public function provideGetTimeBetween(): array ]; } - /** - * @dataProvider provideGetTimeBetween - */ + #[DataProvider('provideGetTimeBetween')] public function testGetTimeBetween(string $timeBefore, string $timeAfter, string $expected): void { $before = (new DBDateTime())->setValue($timeBefore); diff --git a/tests/php/ORM/DBEnumTest.php b/tests/php/ORM/DBEnumTest.php index c0d1f71c0b1..a44fbc57f51 100644 --- a/tests/php/ORM/DBEnumTest.php +++ b/tests/php/ORM/DBEnumTest.php @@ -6,6 +6,7 @@ use SilverStripe\ORM\FieldType\DBEnum; use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\DB; +use PHPUnit\Framework\Attributes\DataProvider; class DBEnumTest extends SapphireTest { @@ -17,11 +18,11 @@ class DBEnumTest extends SapphireTest protected $usesDatabase = true; /** - * @dataProvider provideParse * * nullifyEmpty is an option on DBString, which DBEnum extends * Mainly used for testing that Enum short-array style syntax works while passing in options */ + #[DataProvider('provideParse')] public function testParse(?string $expectedDefault, bool $expectedNullifyEmpty, string $spec) { /** @var DBEnum $enum */ @@ -31,7 +32,7 @@ public function testParse(?string $expectedDefault, bool $expectedNullifyEmpty, $this->assertEquals($expectedNullifyEmpty, $enum->getNullifyEmpty()); } - public function provideParse() + public static function provideParse() { return [ // standard syntax - double quotes diff --git a/tests/php/ORM/DBFieldTest.php b/tests/php/ORM/DBFieldTest.php index cb1cb0ae727..b64cebf1bfe 100644 --- a/tests/php/ORM/DBFieldTest.php +++ b/tests/php/ORM/DBFieldTest.php @@ -29,6 +29,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBYear; +use PHPUnit\Framework\Attributes\DataProvider; /** * Tests for DBField objects. @@ -206,9 +207,7 @@ public function testPrepValueForDB() $this->assertEquals(PHP_INT_MAX, $bigInt->getValue()); } - /** - * @dataProvider dataProviderPrepValueForDBArrayValue - */ + #[DataProvider('dataProviderPrepValueForDBArrayValue')] public function testPrepValueForDBArrayValue($dbFieldName, $scalarValueOnly, $extraArgs = []) { $reflection = new \ReflectionClass($dbFieldName); @@ -226,7 +225,7 @@ public function testPrepValueForDBArrayValue($dbFieldName, $scalarValueOnly, $ex $this->assertEquals($scalarValueOnly, $dbField->scalarValueOnly()); } - public function dataProviderPrepValueForDBArrayValue() + public static function dataProviderPrepValueForDBArrayValue() { return [ [DBBigInt::class, true], diff --git a/tests/php/ORM/DBHTMLTextTest.php b/tests/php/ORM/DBHTMLTextTest.php index 8ab5b8bcdb6..57aaf0ea9b2 100644 --- a/tests/php/ORM/DBHTMLTextTest.php +++ b/tests/php/ORM/DBHTMLTextTest.php @@ -11,6 +11,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\Tests\DBHTMLTextTest\TestShortcode; use SilverStripe\View\Parsers\ShortcodeParser; +use PHPUnit\Framework\Attributes\DataProvider; class DBHTMLTextTest extends SapphireTest { @@ -45,7 +46,7 @@ protected function tearDown(): void /** * Test {@link Text->LimitCharacters()} */ - public function providerLimitCharacters() + public static function providerLimitCharacters() { // HTML characters are stripped safely return [ @@ -58,10 +59,10 @@ public function providerLimitCharacters() /** * Test {@link DBHTMLText->LimitCharacters()} * - * @dataProvider providerLimitCharacters * @param string $originalValue * @param string $expectedValue */ + #[DataProvider('providerLimitCharacters')] public function testLimitCharacters($originalValue, $expectedValue) { $textObj = DBField::create_field('HTMLFragment', $originalValue); @@ -72,7 +73,7 @@ public function testLimitCharacters($originalValue, $expectedValue) /** * @return array */ - public function providerLimitCharactersToClosestWord() + public static function providerLimitCharactersToClosestWord() { // HTML is converted safely to plain text return [ @@ -98,12 +99,12 @@ public function providerLimitCharactersToClosestWord() /** * Test {@link DBHTMLText->LimitCharactersToClosestWord()} * - * @dataProvider providerLimitCharactersToClosestWord * * @param string $originalValue Raw string input * @param int $limit * @param string $expectedValue Expected template value */ + #[DataProvider('providerLimitCharactersToClosestWord')] public function testLimitCharactersToClosestWord($originalValue, $limit, $expectedValue) { $textObj = DBField::create_field('HTMLFragment', $originalValue); @@ -111,7 +112,7 @@ public function testLimitCharactersToClosestWord($originalValue, $limit, $expect $this->assertEquals($expectedValue, $result); } - public function providerSummary() + public static function providerSummary() { return [ [ @@ -167,11 +168,11 @@ public function providerSummary() } /** - * @dataProvider providerSummary * @param string $originalValue * @param int $limit * @param string $expectedValue */ + #[DataProvider('providerSummary')] public function testSummary($originalValue, $limit, $expectedValue) { $textObj = DBField::create_field('HTMLFragment', $originalValue); @@ -199,7 +200,7 @@ public function testSummaryEndings() - public function providerFirstSentence() + public static function providerFirstSentence() { return [ // Same behaviour as DBTextTest @@ -216,10 +217,10 @@ public function providerFirstSentence() } /** - * @dataProvider providerFirstSentence * @param string $originalValue * @param string $expectedValue */ + #[DataProvider('providerFirstSentence')] public function testFirstSentence($originalValue, $expectedValue) { $textObj = DBField::create_field('HTMLFragment', $originalValue); @@ -251,7 +252,7 @@ public function testCreate() $this->assertEquals(['a'], $field->getWhitelist()); } - public function providerToPlain() + public static function providerToPlain() { return [ [ @@ -274,10 +275,10 @@ public function providerToPlain() } /** - * @dataProvider providerToPlain * @param string $html * @param string $plain */ + #[DataProvider('providerToPlain')] public function testToPlain($html, $plain) { /** @@ -292,7 +293,7 @@ public function testToPlain($html, $plain) * * @return array */ - public function providerContextSummary() + public static function providerContextSummary() { return [ [ @@ -358,12 +359,12 @@ public function providerContextSummary() } /** - * @dataProvider providerContextSummary * @param string $originalValue Input * @param int $limit Number of characters * @param string $keywords Keywords to highlight * @param string $expectedValue Expected output (XML encoded safely) */ + #[DataProvider('providerContextSummary')] public function testContextSummary($originalValue, $limit, $keywords, $expectedValue) { $text = DBField::create_field('HTMLFragment', $originalValue); diff --git a/tests/php/ORM/DBSchemaManagerTest.php b/tests/php/ORM/DBSchemaManagerTest.php index f6b5da381ab..a273111c035 100644 --- a/tests/php/ORM/DBSchemaManagerTest.php +++ b/tests/php/ORM/DBSchemaManagerTest.php @@ -7,12 +7,14 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\Connect\DBSchemaManager; use SilverStripe\ORM\Tests\DBSchemaManagerTest\ChildClass; +use PHPUnit\Framework\Attributes\DataProvider; +use SilverStripe\ORM\Tests\DBSchemaManagerTest\TestDBSchemaManager; class DBSchemaManagerTest extends SapphireTest { protected $usesDatabase = false; - public function provideCanCheckAndRepairTable() + public static function provideCanCheckAndRepairTable() { return [ // not ignored, but globally not allowed @@ -48,9 +50,7 @@ public function provideCanCheckAndRepairTable() ]; } - /** - * @dataProvider provideCanCheckAndRepairTable - */ + #[DataProvider('provideCanCheckAndRepairTable')] public function testCanCheckAndRepairTable(string $tableName, bool $checkAndRepairOnBuild, bool $expected) { // set config @@ -72,6 +72,6 @@ public function testCanCheckAndRepairTable(string $tableName, bool $checkAndRepa */ private function getConcreteSchemaManager(): DBSchemaManager { - return $this->getMockBuilder(DBSchemaManager::class)->getMockForAbstractClass(); + return new TestDBSchemaManager(); } } diff --git a/tests/php/ORM/DBSchemaManagerTest/TestDBSchemaManager.php b/tests/php/ORM/DBSchemaManagerTest/TestDBSchemaManager.php new file mode 100644 index 00000000000..f7ddf5893e3 --- /dev/null +++ b/tests/php/ORM/DBSchemaManagerTest/TestDBSchemaManager.php @@ -0,0 +1,170 @@ +assertEquals( @@ -35,9 +32,6 @@ public function testDefault() ); } - /** - * @covers \SilverStripe\ORM\FieldType\DBString::LowerCase() - */ public function testLowerCase() { /** @var MyStringField $field */ @@ -48,9 +42,6 @@ public function testLowerCase() ); } - /** - * @covers \SilverStripe\ORM\FieldType\DBString::UpperCase() - */ public function testUpperCase() { /** @var MyStringField $field */ diff --git a/tests/php/ORM/DBTextTest.php b/tests/php/ORM/DBTextTest.php index cb2f0fa487c..98be89fca23 100644 --- a/tests/php/ORM/DBTextTest.php +++ b/tests/php/ORM/DBTextTest.php @@ -5,6 +5,7 @@ use SilverStripe\ORM\FieldType\DBField; use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\FieldType\DBText; +use PHPUnit\Framework\Attributes\DataProvider; /** * Tests parsing and summary methods on DBText @@ -33,7 +34,7 @@ protected function tearDown(): void /** * Test {@link Text->LimitCharacters()} */ - public function providerLimitCharacters() + public static function providerLimitCharacters() { // Plain text values always encoded safely // HTML stored in non-html fields is treated literally. @@ -48,10 +49,10 @@ public function providerLimitCharacters() /** * Test {@link Text->LimitCharacters()} * - * @dataProvider providerLimitCharacters * @param string $originalValue * @param string $expectedValue */ + #[DataProvider('providerLimitCharacters')] public function testLimitCharacters($originalValue, $expectedValue) { $textObj = DBField::create_field('Text', $originalValue); @@ -62,7 +63,7 @@ public function testLimitCharacters($originalValue, $expectedValue) /** * @return array */ - public function providerLimitCharactersToClosestWord() + public static function providerLimitCharactersToClosestWord() { return [ // Standard words limited, ellipsis added if truncated @@ -91,12 +92,12 @@ public function providerLimitCharactersToClosestWord() /** * Test {@link Text->LimitCharactersToClosestWord()} * - * @dataProvider providerLimitCharactersToClosestWord * * @param string $originalValue Raw string input * @param int $limit * @param string $expectedValue Expected template value */ + #[DataProvider('providerLimitCharactersToClosestWord')] public function testLimitCharactersToClosestWord($originalValue, $limit, $expectedValue) { $textObj = DBField::create_field('Text', $originalValue); @@ -107,7 +108,7 @@ public function testLimitCharactersToClosestWord($originalValue, $limit, $expect /** * Test {@link Text->LimitWordCount()} */ - public function providerLimitWordCount() + public static function providerLimitWordCount() { return [ // Standard words limited, ellipsis added if truncated @@ -137,12 +138,12 @@ public function providerLimitWordCount() /** * Test {@link DBText->LimitWordCount()} * - * @dataProvider providerLimitWordCount * * @param string $originalValue Raw string input * @param int $limit Number of words * @param string $expectedValue Expected template value */ + #[DataProvider('providerLimitWordCount')] public function testLimitWordCount($originalValue, $limit, $expectedValue) { $textObj = DBField::create_field('Text', $originalValue); @@ -150,9 +151,7 @@ public function testLimitWordCount($originalValue, $limit, $expectedValue) $this->assertEquals($expectedValue, $result); } - /** - */ - public function providerLimitSentences() + public static function providerLimitSentences() { return [ ['', 2, ''], @@ -172,11 +171,11 @@ public function providerLimitSentences() /** * Test {@link DBText->LimitSentences()} * - * @dataProvider providerLimitSentences * @param string $originalValue * @param int $limit Number of sentences * @param string $expectedValue Expected template value */ + #[DataProvider('providerLimitSentences')] public function testLimitSentences($originalValue, $limit, $expectedValue) { $textObj = DBField::create_field('Text', $originalValue); @@ -184,7 +183,7 @@ public function testLimitSentences($originalValue, $limit, $expectedValue) $this->assertEquals($expectedValue, $result); } - public function providerFirstSentence() + public static function providerFirstSentence() { return [ ['', ''], @@ -204,10 +203,10 @@ public function providerFirstSentence() } /** - * @dataProvider providerFirstSentence * @param string $originalValue * @param string $expectedValue */ + #[DataProvider('providerFirstSentence')] public function testFirstSentence($originalValue, $expectedValue) { $textObj = DBField::create_field('Text', $originalValue); @@ -220,7 +219,7 @@ public function testFirstSentence($originalValue, $expectedValue) * * @return array */ - public function providerContextSummary() + public static function providerContextSummary() { return [ [ @@ -279,7 +278,7 @@ public function providerContextSummary() * * @return array */ - public function providerSummary() + public static function providerSummary() { return [ 'simple test' => [ @@ -336,12 +335,12 @@ public function providerSummary() } /** - * @dataProvider providerContextSummary * @param string $originalValue Input * @param int $limit Number of characters * @param string $keywords Keywords to highlight * @param string $expectedValue Expected output (XML encoded safely) */ + #[DataProvider('providerContextSummary')] public function testContextSummary($originalValue, $limit, $keywords, $expectedValue) { $text = DBField::create_field('Text', $originalValue); @@ -413,12 +412,12 @@ public function testDefaultEllipsis() } /** - * @dataProvider providerSummary * @param string $originalValue Input * @param int $words Number of words * @param mixed $add Ellipsis (false for default or string for custom text) * @param string $expectedValue Expected output (XML encoded safely) */ + #[DataProvider('providerSummary')] public function testSummary($originalValue, $words, $add, $expectedValue) { $text = DBField::create_field(DBText::class, $originalValue); diff --git a/tests/php/ORM/DBTimeTest.php b/tests/php/ORM/DBTimeTest.php index fa2420c5f8f..2d5135fe029 100644 --- a/tests/php/ORM/DBTimeTest.php +++ b/tests/php/ORM/DBTimeTest.php @@ -7,6 +7,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\FieldType\DBTime; use SilverStripe\Security\Member; +use PHPUnit\Framework\Attributes\DataProvider; class DBTimeTest extends SapphireTest { @@ -16,7 +17,7 @@ protected function setUp(): void i18n::set_locale('en_NZ'); } - public function dataTestParse() + public static function dataTestParse() { return [ // Test am-pm conversion @@ -31,10 +32,10 @@ public function dataTestParse() } /** - * @dataProvider dataTestParse * @param string $input * @param string $expected */ + #[DataProvider('dataTestParse')] public function testParse($input, $expected) { $time = DBField::create_field('Time', $input); diff --git a/tests/php/ORM/DataListEagerLoadingTest.php b/tests/php/ORM/DataListEagerLoadingTest.php index 13c2460c8f8..abab2fbb909 100644 --- a/tests/php/ORM/DataListEagerLoadingTest.php +++ b/tests/php/ORM/DataListEagerLoadingTest.php @@ -39,6 +39,7 @@ use SilverStripe\ORM\Tests\DataListTest\EagerLoading\MixedHasManyEagerLoadObject; use SilverStripe\ORM\Tests\DataListTest\EagerLoading\MixedHasOneEagerLoadObject; use SilverStripe\ORM\Tests\DataListTest\EagerLoading\MixedManyManyEagerLoadObject; +use PHPUnit\Framework\Attributes\DataProvider; class DataListEagerLoadingTest extends SapphireTest { @@ -162,9 +163,7 @@ private function resetShowQueries(): void $this->showQueries = DataListEagerLoadingTest::SHOW_QUERIES_RESET; } - /** - * @dataProvider provideEagerLoadRelations - */ + #[DataProvider('provideEagerLoadRelations')] public function testEagerLoadRelations(string $iden, array $eagerLoad, int $expected): void { $this->createEagerLoadData(); @@ -180,7 +179,7 @@ public function testEagerLoadRelations(string $iden, array $eagerLoad, int $expe $this->assertSame($expected, $selectCount); } - public function provideEagerLoadRelations(): array + public static function provideEagerLoadRelations(): array { return [ // Include the lazy-loaded expectation here, since if the number @@ -756,9 +755,7 @@ private function iterateEagerLoadData(DataList $dataList, int $chunks = 0): arra return [$results, $selectCount]; } - /** - * @dataProvider provideEagerLoadRelationsEmpty - */ + #[DataProvider('provideEagerLoadRelationsEmpty')] public function testEagerLoadRelationsEmpty(string $eagerLoadRelation, int $expectedNumQueries): void { EagerLoadObject::create(['Title' => 'test object'])->write(); @@ -779,35 +776,35 @@ public function testEagerLoadRelationsEmpty(string $eagerLoadRelation, int $expe $this->assertSame($expectedNumQueries, $numQueries); } - public function provideEagerLoadRelationsEmpty(): array + public static function provideEagerLoadRelationsEmpty(): array { return [ 'has_one' => [ - 'eagerLoad' => 'HasOneEagerLoadObject', + 'eagerLoadRelation' => 'HasOneEagerLoadObject', 'expectedNumQueries' => 1, ], 'polymorph_has_one' => [ - 'eagerLoad' => 'HasOnePolymorphObject', + 'eagerLoadRelation' => 'HasOnePolymorphObject', 'expectedNumQueries' => 1, ], 'belongs_to' => [ - 'eagerLoad' => 'BelongsToEagerLoadObject', + 'eagerLoadRelation' => 'BelongsToEagerLoadObject', 'expectedNumQueries' => 2, ], 'has_many' => [ - 'eagerLoad' => 'HasManyEagerLoadObjects', + 'eagerLoadRelation' => 'HasManyEagerLoadObjects', 'expectedNumQueries' => 2, ], 'many_many' => [ - 'eagerLoad' => 'ManyManyEagerLoadObjects', + 'eagerLoadRelation' => 'ManyManyEagerLoadObjects', 'expectedNumQueries' => 2, ], 'many_many through' => [ - 'eagerLoad' => 'ManyManyThroughEagerLoadObjects', + 'eagerLoadRelation' => 'ManyManyThroughEagerLoadObjects', 'expectedNumQueries' => 2, ], 'belongs_many_many' => [ - 'eagerLoad' => 'BelongsManyManyEagerLoadObjects', + 'eagerLoadRelation' => 'BelongsManyManyEagerLoadObjects', 'expectedNumQueries' => 2, ], ]; @@ -830,9 +827,7 @@ public function testEagerLoadFourthLevelException(): void EagerLoadObject::get()->eagerLoad($eagerLoadRelation); } - /** - * @dataProvider provideEagerLoadInvalidRelationException - */ + #[DataProvider('provideEagerLoadInvalidRelationException')] public function testEagerLoadInvalidRelationException(string $eagerLoadRelation): void { $this->expectException(InvalidArgumentException::class); @@ -841,7 +836,7 @@ public function testEagerLoadInvalidRelationException(string $eagerLoadRelation) EagerLoadObject::get()->eagerLoad($eagerLoadRelation)->toArray(); } - public function provideEagerLoadInvalidRelationException(): array + public static function provideEagerLoadInvalidRelationException(): array { return [ [ @@ -856,9 +851,7 @@ public function provideEagerLoadInvalidRelationException(): array ]; } - /** - * @dataProvider provideEagerLoadManyManyExtraFields - */ + #[DataProvider('provideEagerLoadManyManyExtraFields')] public function testEagerLoadManyManyExtraFields(string $parentClass, string $eagerLoadRelation): void { $this->createEagerLoadData(); @@ -887,7 +880,7 @@ private function validateEagerLoadManyManyExtraFields($relationList): void } } - public function provideEagerLoadManyManyExtraFields(): array + public static function provideEagerLoadManyManyExtraFields(): array { return [ [ @@ -901,9 +894,7 @@ public function provideEagerLoadManyManyExtraFields(): array ]; } - /** - * @dataProvider provideEagerLoadManyManyThroughJoinRecords - */ + #[DataProvider('provideEagerLoadManyManyThroughJoinRecords')] public function testEagerLoadManyManyThroughJoinRecords(string $parentClass, string $eagerLoadRelation): void { $this->createEagerLoadData(); @@ -936,7 +927,7 @@ private function validateEagerLoadManyManyThroughJoinRecords($relationList): voi } } - public function provideEagerLoadManyManyThroughJoinRecords(): array + public static function provideEagerLoadManyManyThroughJoinRecords(): array { return [ [ @@ -950,10 +941,8 @@ public function provideEagerLoadManyManyThroughJoinRecords(): array ]; } - /** - * @dataProvider provideEagerLoadRelations - */ - public function testEagerLoadingFilteredList(string $iden, array $eagerLoad): void + #[DataProvider('provideEagerLoadRelations')] + public function testEagerLoadingFilteredList(string $iden, array $eagerLoad, int $expected): void { $this->createEagerLoadData(5); $filter = ['Title:GreaterThan' => 'obj 0']; @@ -970,10 +959,8 @@ public function testEagerLoadingFilteredList(string $iden, array $eagerLoad): vo $this->validateEagerLoadingResults($iden, EagerLoadObject::get()->filter($filter), $dataList); } - /** - * @dataProvider provideEagerLoadRelations - */ - public function testEagerLoadingSortedList(string $iden, array $eagerLoad): void + #[DataProvider('provideEagerLoadRelations')] + public function testEagerLoadingSortedList(string $iden, array $eagerLoad, int $expected): void { $this->createEagerLoadData(3); $items = [ @@ -999,10 +986,8 @@ public function testEagerLoadingSortedList(string $iden, array $eagerLoad): void $this->validateEagerLoadingResults($iden, EagerLoadObject::get()->sort($sort), $dataList); } - /** - * @dataProvider provideEagerLoadRelations - */ - public function testEagerLoadingLimitedList(string $iden, array $eagerLoad): void + #[DataProvider('provideEagerLoadRelations')] + public function testEagerLoadingLimitedList(string $iden, array $eagerLoad, int $expected): void { // Make sure to create more base records AND more records on at least one relation than the limit // to ensure the limit isn't accidentally carried through to the relations. @@ -1016,10 +1001,8 @@ public function testEagerLoadingLimitedList(string $iden, array $eagerLoad): voi $this->validateEagerLoadingResults($iden, EagerLoadObject::get()->limit($limit), $dataList); } - /** - * @dataProvider provideEagerLoadRelations - */ - public function testRepeatedIterationOfEagerLoadedList(string $iden, array $eagerLoad): void + #[DataProvider('provideEagerLoadRelations')] + public function testRepeatedIterationOfEagerLoadedList(string $iden, array $eagerLoad, int $expected): void { // We need at least 3 base records for many_many relations to have fewer db queries than lazy-loaded lists. $this->createEagerLoadData(3); @@ -1034,10 +1017,9 @@ public function testRepeatedIterationOfEagerLoadedList(string $iden, array $eage * This test validates that you can call eagerLoad() anywhere on the list before * execution, including before or after sort/limit/filter, etc - and it will * work the same way regardless of when it was called. - * - * @dataProvider provideEagerLoadRelations */ - public function testEagerLoadWorksAnywhereBeforeExecution(string $iden, array $eagerLoad): void + #[DataProvider('provideEagerLoadRelations')] + public function testEagerLoadWorksAnywhereBeforeExecution(string $iden, array $eagerLoad, int $expected): void { $this->createEagerLoadData(7); $filter = ['Title:LessThan' => 'obj 5']; @@ -1066,10 +1048,8 @@ public function testEagerLoadWorksAnywhereBeforeExecution(string $iden, array $e $this->validateEagerLoadingResults($iden, $lazyList, $eagerList4); } - /** - * @dataProvider provideEagerLoadRelations - */ - public function testEagerLoadWithChunkedFetch(string $iden, array $eagerLoad): void + #[DataProvider('provideEagerLoadRelations')] + public function testEagerLoadWithChunkedFetch(string $iden, array $eagerLoad, int $expected): void { $this->createEagerLoadData(10); $dataList = EagerLoadObject::get()->eagerLoad(...$eagerLoad); @@ -1098,9 +1078,7 @@ private function validateEagerLoadingResults(string $iden, DataList $lazyList, D } } - /** - * @dataProvider provideEagerLoadingEmptyRelations - */ + #[DataProvider('provideEagerLoadingEmptyRelations')] public function testEagerLoadingEmptyRelations(string $iden, string $eagerLoad): void { $numBaseRecords = 3; @@ -1251,7 +1229,7 @@ public function testEagerLoadingEmptyRelations(string $iden, string $eagerLoad): } } - public function provideEagerLoadingEmptyRelations(): array + public static function provideEagerLoadingEmptyRelations(): array { return [ [ @@ -1362,7 +1340,7 @@ public function testInvalidAssociativeArray(): void EagerLoadObject::get()->eagerLoad(['HasManyEagerLoadObjects' => 'HasManyEagerLoadObjects']); } - public function provideNoLimitEagerLoadingQuery(): array + public static function provideNoLimitEagerLoadingQuery(): array { // Note we don't test has_one or belongs_to because those don't accept a callback at all. return [ @@ -1391,9 +1369,8 @@ public function provideNoLimitEagerLoadingQuery(): array /** * Tests that attempting to limit an eagerloading query will throw an exception. - * - * @dataProvider provideNoLimitEagerLoadingQuery */ + #[DataProvider('provideNoLimitEagerLoadingQuery')] public function testNoLimitEagerLoadingQuery(string $relation, string $relationType, callable $callback): void { // Need to have at least one record in the main list for eagerloading to even be triggered. @@ -1407,7 +1384,7 @@ public function testNoLimitEagerLoadingQuery(string $relation, string $relationT EagerLoadObject::get()->eagerLoad([$relation => $callback])->toArray(); } - public function provideCannotManipulateUnaryRelationQuery(): array + public static function provideCannotManipulateUnaryRelationQuery(): array { return [ 'has_one' => [ @@ -1423,9 +1400,8 @@ public function provideCannotManipulateUnaryRelationQuery(): array /** * Tests that attempting to manipulate a has_one or belongs_to eagerloading query will throw an exception. - * - * @dataProvider provideCannotManipulateUnaryRelationQuery */ + #[DataProvider('provideCannotManipulateUnaryRelationQuery')] public function testCannotManipulateUnaryRelationQuery(string $relation, string $relationType): void { // Need to have at least one record in the main list for eagerloading to even be triggered. @@ -1458,7 +1434,7 @@ public function testManipulatingEagerloadingQueryNoReturn(): void ])->toArray(); } - public function provideManipulatingEagerloadingQuery(): array + public static function provideManipulatingEagerloadingQuery(): array { return [ 'nested has_many' => [ @@ -1586,9 +1562,8 @@ public function provideManipulatingEagerloadingQuery(): array /** * Tests that callbacks can be used to manipulate eagerloading queries - * - * @dataProvider provideManipulatingEagerloadingQuery */ + #[DataProvider('provideManipulatingEagerloadingQuery')] public function testManipulatingEagerloadingQuery(string $relationType, array $relations, array $eagerLoad, array $expected): void { $relationNames = array_keys($relations); diff --git a/tests/php/ORM/DataListTest.php b/tests/php/ORM/DataListTest.php index b5fbdf63a64..ca232778c54 100755 --- a/tests/php/ORM/DataListTest.php +++ b/tests/php/ORM/DataListTest.php @@ -34,6 +34,7 @@ use SilverStripe\ORM\Filters\SearchFilter; use SilverStripe\ORM\Tests\DataObjectTest\RelationChildFirst; use SilverStripe\ORM\Tests\DataObjectTest\RelationChildSecond; +use PHPUnit\Framework\Attributes\DataProvider; class DataListTest extends SapphireTest { @@ -89,7 +90,7 @@ public function testFilterDataObjectByCreatedDate() $this->assertEquals(2, count($list ?? [])); } - public function provideDefaultCaseSensitivity() + public static function provideDefaultCaseSensitivity() { return [ [ @@ -135,9 +136,7 @@ public function provideDefaultCaseSensitivity() ]; } - /** - * @dataProvider provideDefaultCaseSensitivity - */ + #[DataProvider('provideDefaultCaseSensitivity')] public function testDefaultCaseSensitivity(bool $caseSensitive, array $filter, int $expectedCount) { SearchFilter::config()->set('default_case_sensitive', $caseSensitive); @@ -203,7 +202,7 @@ public function testListCreationSortAndLimit() $this->assertEquals(['Joe', 'Phil'], $list->limit(2, 1)->column('Name')); } - public function limitDataProvider(): array + public static function limitDataProvider(): array { return [ 'no limit' => [null, 0, 3], @@ -220,9 +219,7 @@ public function limitDataProvider(): array ]; } - /** - * @dataProvider limitDataProvider - */ + #[DataProvider('limitDataProvider')] public function testLimitAndOffset($length, $offset, $expectedCount, $expectException = false) { $list = TeamComment::get(); @@ -304,7 +301,7 @@ public function testSql() $this->assertSQLEquals($expected, $list->sql($parameters)); } - public function provideJoin() + public static function provideJoin() { return [ [ @@ -322,9 +319,7 @@ public function provideJoin() ]; } - /** - * @dataProvider provideJoin - */ + #[DataProvider('provideJoin')] public function testJoin(string $joinMethod, string $joinType) { $db = DB::get_conn(); @@ -352,9 +347,7 @@ public function testJoin(string $joinMethod, string $joinType) $this->assertEmpty($parameters); } - /** - * @dataProvider provideJoin - */ + #[DataProvider('provideJoin')] public function testJoinParameterised(string $joinMethod, string $joinType) { $db = DB::get_conn(); @@ -680,7 +673,7 @@ public function testSortWithCompositeSyntax() public function testSortInvalidParameters() { $this->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 } @@ -1897,9 +1890,6 @@ public function testMultipleExcludeWithTwoArrayOneTeam() $this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil'); } - /** - * - */ public function testSortByRelation() { $list = TeamComment::get(); @@ -1948,9 +1938,7 @@ public function testOrderByComplexExpression() ); } - /** - * @dataProvider provideRawSqlSortException - */ + #[DataProvider('provideRawSqlSortException')] public function testRawSqlSort(string $sort, string $type): void { $type = explode('|', $type)[0]; @@ -1978,9 +1966,7 @@ public function testRawSqlSort(string $sort, string $type): void Team::get()->sort($sort)->column('ID'); } - /** - * @dataProvider provideRawSqlSortException - */ + #[DataProvider('provideRawSqlSortException')] public function testRawSqlOrderBy(string $sort, string $type): void { $type = explode('|', $type)[1]; @@ -2005,7 +1991,7 @@ public function testRawSqlOrderBy(string $sort, string $type): void Team::get()->orderBy($sort)->column('ID'); } - public function provideRawSqlSortException(): array + public static function provideRawSqlSortException(): array { return [ ['Title', 'valid|valid'], @@ -2033,9 +2019,7 @@ public function provideRawSqlSortException(): array ]; } - /** - * @dataProvider provideSortDirectionValidationTwoArgs - */ + #[DataProvider('provideSortDirectionValidationTwoArgs')] public function testSortDirectionValidationTwoArgs(string $direction, string $type): void { if ($type === 'valid') { @@ -2047,7 +2031,7 @@ public function testSortDirectionValidationTwoArgs(string $direction, string $ty Team::get()->sort('Title', $direction)->column('ID'); } - public function provideSortDirectionValidationTwoArgs(): array + public static function provideSortDirectionValidationTwoArgs(): array { return [ ['ASC', 'valid'], @@ -2060,9 +2044,8 @@ public function provideSortDirectionValidationTwoArgs(): array /** * Test passing scalar values to sort() - * - * @dataProvider provideSortScalarValues */ + #[DataProvider('provideSortScalarValues')] public function testSortScalarValues(mixed $emtpyValue, string $type): void { $this->assertSame(['Subteam 1'], Team::get()->limit(1)->column('Title')); @@ -2080,7 +2063,7 @@ public function testSortScalarValues(mixed $emtpyValue, string $type): void $this->assertSame(['Subteam 1'], $list->limit(1)->column('Title')); } - public function provideSortScalarValues(): array + public static function provideSortScalarValues(): array { return [ ['', 'empty-scalar'], @@ -2261,9 +2244,7 @@ public function testOffsetUnset() $list->offsetUnset(0); } - /** - * @dataProvider provideRelation - */ + #[DataProvider('provideRelation')] public function testRelation(string $parentClass, string $relation, ?array $expected) { $list = $parentClass::get()->relation($relation); @@ -2274,7 +2255,7 @@ public function testRelation(string $parentClass, string $relation, ?array $expe } } - public function provideRelation() + public static function provideRelation() { return [ 'many_many' => [ @@ -2302,9 +2283,7 @@ public function provideRelation() ]; } - /** - * @dataProvider provideCreateDataObject - */ + #[DataProvider('provideCreateDataObject')] public function testCreateDataObject(string $dataClass, string $realClass, array $row) { $list = new DataList($dataClass); @@ -2326,7 +2305,7 @@ public function testCreateDataObject(string $dataClass, string $realClass, array } } - public function provideCreateDataObject() + public static function provideCreateDataObject() { return [ 'no ClassName' => [ diff --git a/tests/php/ORM/DataObjectSchemaTest.php b/tests/php/ORM/DataObjectSchemaTest.php index e4d122e1b4f..6dc78b5d76f 100644 --- a/tests/php/ORM/DataObjectSchemaTest.php +++ b/tests/php/ORM/DataObjectSchemaTest.php @@ -21,6 +21,7 @@ use SilverStripe\ORM\Tests\DataObjectSchemaTest\NoFields; use SilverStripe\ORM\Tests\DataObjectSchemaTest\WithCustomTable; use SilverStripe\ORM\Tests\DataObjectSchemaTest\WithRelation; +use PHPUnit\Framework\Attributes\DataProvider; /** * Tests schema inspection of DataObjects @@ -159,9 +160,7 @@ public function testTableForObjectField() ); } - /** - * @dataProvider provideFieldSpec - */ + #[DataProvider('provideFieldSpec')] public function testFieldSpec(array $args, array $expected): void { $schema = DataObject::getSchema(); @@ -173,7 +172,7 @@ public function testFieldSpec(array $args, array $expected): void $this->assertEquals($expected, $schema->fieldSpecs(...$args)); } - public function provideFieldSpec(): array + public static function provideFieldSpec(): array { return [ 'just pass a class' => [ @@ -254,9 +253,6 @@ public function provideFieldSpec(): array ]; } - /** - * @covers \SilverStripe\ORM\DataObjectSchema::baseDataClass() - */ public function testBaseDataClass() { $schema = DataObject::getSchema(); @@ -405,16 +401,14 @@ public function testWriteUniqueIndexes() ); } - /** - * @dataProvider provideHasOneComponent - */ + #[DataProvider('provideHasOneComponent')] public function testHasOneComponent(string $class, string $component, string $expected): void { $this->assertSame($expected, DataObject::getSchema()->hasOneComponent($class, $component)); } - public function provideHasOneComponent(): array + public static function provideHasOneComponent(): array { return [ [ @@ -440,9 +434,7 @@ public function provideHasOneComponent(): array ]; } - /** - * @dataProvider provideHasOneComponentHandlesMultipleRelations - */ + #[DataProvider('provideHasOneComponentHandlesMultipleRelations')] public function testHasOneComponentHandlesMultipleRelations(string $class, string $component, bool $expected): void { $this->assertSame( @@ -451,7 +443,7 @@ public function testHasOneComponentHandlesMultipleRelations(string $class, strin ); } - public function provideHasOneComponentHandlesMultipleRelations(): array + public static function provideHasOneComponentHandlesMultipleRelations(): array { return [ [ diff --git a/tests/php/ORM/DataObjectTest.php b/tests/php/ORM/DataObjectTest.php index 5bb51505dcb..d4ce517c307 100644 --- a/tests/php/ORM/DataObjectTest.php +++ b/tests/php/ORM/DataObjectTest.php @@ -27,6 +27,7 @@ use SilverStripe\View\ViewableData; use ReflectionMethod; use stdClass; +use PHPUnit\Framework\Attributes\DataProvider; class DataObjectTest extends SapphireTest { @@ -92,9 +93,7 @@ public static function getExtraDataObjects() ); } - /** - * @dataProvider provideSingletons - */ + #[DataProvider('provideSingletons')] public function testSingleton($inst, $defaultValue, $altDefaultValue) { $inst = $inst(); @@ -113,7 +112,7 @@ public function testSingleton($inst, $defaultValue, $altDefaultValue) } } - public function provideSingletons() + public static function provideSingletons() { // because PHPUnit evaluates test providers *before* setUp methods // any extensions added in the setUp methods won't be available @@ -2674,7 +2673,7 @@ public function testSettersAndGettersAreRespected() $this->assertSame('SOME VALUE', $obj->MyTestField); } - public function provideTestGetDatabaseBackedField() + public static function provideTestGetDatabaseBackedField() { return [ ['Captain.IsRetired', 'Captain.IsRetired'], @@ -2704,9 +2703,7 @@ public function provideTestGetDatabaseBackedField() ]; } - /** - * @dataProvider provideTestGetDatabaseBackedField - */ + #[DataProvider('provideTestGetDatabaseBackedField')] public function testGetDatabaseBackedField(string $fieldPath, $expected) { $dataObjectClass = new DataObject(); diff --git a/tests/php/ORM/DataQueryTest.php b/tests/php/ORM/DataQueryTest.php index b0cfc9103ae..d4969dfe739 100644 --- a/tests/php/ORM/DataQueryTest.php +++ b/tests/php/ORM/DataQueryTest.php @@ -10,6 +10,11 @@ use SilverStripe\ORM\Queries\SQLSelect; use SilverStripe\ORM\Tests\DataQueryTest\ObjectE; use SilverStripe\Security\Member; +use SilverStripe\ORM\Tests\DataQueryTest\DataQueryTestException; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\DoesNotPerformAssertions; +use SilverStripe\Dev\Exceptions\ExpectedErrorException; +use SilverStripe\Dev\Exceptions\ExpectedWarningException; class DataQueryTest extends SapphireTest { @@ -56,7 +61,7 @@ public function testSortByJoinedFieldRetainsSourceInformation() $this->assertEquals('Foo', $result['Title']); } - public function provideJoins() + public static function provideJoins() { return [ [ @@ -74,9 +79,7 @@ public function provideJoins() ]; } - /** - * @dataProvider provideJoins - */ + #[DataProvider('provideJoins')] public function testJoins($joinMethod, $joinType) { $dq = new DataQuery(Member::class); @@ -101,9 +104,7 @@ public function testApplyRelation() $this->assertStringContainsString('"testctwo_DataQueryTest_C"."ID" = "DataQueryTest_B"."TestCTwoID"', $dq->sql()); } - /** - * @dataProvider provideApplyRelationMultiRelational - */ + #[DataProvider('provideApplyRelationMultiRelational')] public function testApplyRelationMultiRelational(string $relation): void { $dq = new DataQuery(DataQueryTest\ObjectHasMultiRelationalHasMany::class); @@ -116,7 +117,7 @@ public function testApplyRelationMultiRelational(string $relation): void $this->assertStringContainsString($joinAliasWithQuotes . '."MultiRelationalClass" = "DataQueryTest_ObjectHasMultiRelationalHasMany"."ClassName"', $dq->sql()); } - public function provideApplyRelationMultiRelational(): array + public static function provideApplyRelationMultiRelational(): array { return [ 'relation1' => [ @@ -215,7 +216,7 @@ public function testRelationOrderWithCustomJoin() $this->assertTrue(true); } - public function provideFieldCollision() + public static function provideFieldCollision() { return [ 'allow collisions' => [true], @@ -223,11 +224,10 @@ public function provideFieldCollision() ]; } - /** - * @dataProvider provideFieldCollision - */ + #[DataProvider('provideFieldCollision')] public function testFieldCollision($allowCollisions) { + $this->enableErrorHandler(); $dataQuery = new DataQuery(DataQueryTest\ObjectB::class); $dataQuery->selectField('COALESCE(NULL, 1) AS "Title"'); $dataQuery->setAllowCollidingFieldStatements($allowCollisions); @@ -235,8 +235,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(ExpectedWarningException::class); + $this->expectExceptionMessageMatches('/^Bad collision item /'); } $dataQuery->getFinalisedQuery(); @@ -604,7 +604,7 @@ public function testExistsCreatesFunctionalQueries() ); } - public function provideWith() + public static function provideWith() { return [ // Simple scenarios to test auto-join functionality @@ -720,7 +720,7 @@ public function provideWith() 'extraManipulations' => [ 'innerJoin' => ['hierarchy', '"SQLSelectTestCteRecursive"."ID" = "hierarchy"."parent_id"'], ], - 'expected' => [ + 'expectedItems' => [ 'fixtures' => [ 'grandparent', 'parent', @@ -731,9 +731,7 @@ public function provideWith() ]; } - /** - * @dataProvider provideWith - */ + #[DataProvider('provideWith')] public function testWith( string $dataClass, string $name, @@ -864,8 +862,8 @@ public function testWithUsingOnlyDataQueries() /** * Tests that CTE queries have appropriate JOINs for subclass tables etc. * If `$query->query()->` was replaced with `$query->query->` in DataQuery::with(), this test would throw an exception. - * @doesNotPerformAssertions */ + #[DoesNotPerformAssertions] public function testWithUsingDataQueryAppliesRelations() { if (!DB::get_conn()->supportsCteQueries()) { 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 @@ +getBasicRecordRows() as $row) { + foreach (EagerLoadedListTest::getBasicRecordRows() as $row) { $list->addRow($row); } $this->assertTrue($list->hasID(3)); @@ -205,9 +206,7 @@ public function testGetRows() $this->assertSame($rows, $list->getRows()); } - /** - * @dataProvider provideAddRowBadID - */ + #[DataProvider('provideAddRowBadID')] public function testAddRowBadID(array $row) { $list = new EagerLoadedList(TeamComment::class, DataList::class); @@ -216,7 +215,7 @@ public function testAddRowBadID(array $row) $list->addRow($row); } - public function provideAddRowBadID() + public static function provideAddRowBadID() { return [ [['ID' => null]], @@ -254,9 +253,7 @@ public function testExists() $this->assertTrue($list->exists()); } - /** - * @dataProvider provideIteration - */ + #[DataProvider('provideIteration')] public function testIteration(string $dataListClass): void { // Get some garbage values for the manymany component so we don't get errors. @@ -270,7 +267,7 @@ public function testIteration(string $dataListClass): void $manyManyComponent['extraFields'] = []; } - $rows = $this->getBasicRecordRows(); + $rows = EagerLoadedListTest::getBasicRecordRows(); $eagerloadedDataClass = Sortable::class; $foreignID = $dataListClass === DataList::class ? null : 9999; @@ -286,7 +283,7 @@ public function testIteration(string $dataListClass): void $this->iterate($list, $rows, array_column($rows, 'ID')); } - public function provideIteration() + public static function provideIteration() { return [ [DataList::class], @@ -296,7 +293,7 @@ public function provideIteration() ]; } - private function iterate(EagerLoadedList $list, array $rows, array $expectedIDs): void + private function iterate(EagerLoadedList $list, array $rows, array $expected): void { $foundIDs = []; foreach ($list as $record) { @@ -314,19 +311,17 @@ private function iterate(EagerLoadedList $list, array $rows, array $expectedIDs) $foundIDs[] = $record->ID; } // Assert all (and only) the expected records were included in the list - $this->assertSame($expectedIDs, $foundIDs); + $this->assertSame($expected, $foundIDs); } - /** - * @dataProvider provideFilter - * @dataProvider provideFilterWithSearchFilters - */ + #[DataProvider('provideFilter')] + #[DataProvider('provideFilterWithSearchFilters')] public function testFilter( string $dataListClass, string $eagerloadedDataClass, array $rows, array $filter, - array $expectedIDs + array $expected, ): void { // Get some garbage values for the manymany component so we don't get errors. // Real relations aren't necessary for this test. @@ -348,41 +343,41 @@ public function testFilter( // Validate that the unfiltered list still has all records, and the filtered list has the expected amount $this->assertCount(count($rows), $list); - $this->assertCount(count($expectedIDs), $filteredList); + $this->assertCount(count($expected), $filteredList); // Validate that the filtered list has the CORRECT records $this->iterate($list, $rows, array_column($rows, 'ID')); } - public function provideFilter(): array + public static function provideFilter(): array { - $rows = $this->getBasicRecordRows(); + $rows = EagerLoadedListTest::getBasicRecordRows(); return [ [ 'dataListClass' => DataList::class, 'eagerloadedDataClass' => ValidatedObject::class, - $rows, + 'rows' => $rows, 'filter' => ['Created' => '2023-01-01 00:00:00'], 'expected' => [2, 3], ], [ 'dataListClass' => HasManyList::class, 'eagerloadedDataClass' => ValidatedObject::class, - $rows, + 'rows' => $rows, 'filter' => ['Created' => '2023-01-01 00:00:00'], 'expected' => [2, 3], ], [ 'dataListClass' => ManyManyList::class, 'eagerloadedDataClass' => ValidatedObject::class, - $rows, + 'rows' => $rows, 'filter' => ['Created' => '2023-12-01 00:00:00'], 'expected' => [], ], [ 'dataListClass' => ManyManyThroughList::class, 'eagerloadedDataClass' => ValidatedObject::class, - $rows, + 'rows' => $rows, 'filter' => [ 'Created' => '2023-01-01 00:00:00', 'Name' => 'test obj 3', @@ -392,7 +387,7 @@ public function provideFilter(): array [ 'dataListClass' => ManyManyThroughList::class, 'eagerloadedDataClass' => ValidatedObject::class, - $rows, + 'rows' => $rows, 'filter' => [ 'Created' => '2023-01-01 00:00:00', 'Name' => 'not there', @@ -402,7 +397,7 @@ public function provideFilter(): array [ 'dataListClass' => ManyManyThroughList::class, 'eagerloadedDataClass' => ValidatedObject::class, - $rows, + 'rows' => $rows, 'filter' => [ 'Name' => ['test obj 1', 'test obj 3', 'not there'], ], @@ -411,7 +406,7 @@ public function provideFilter(): array [ 'dataListClass' => ManyManyThroughList::class, 'eagerloadedDataClass' => ValidatedObject::class, - $rows, + 'rows' => $rows, 'filter' => [ 'Name' => ['not there', 'also not there'], ], @@ -420,7 +415,7 @@ public function provideFilter(): array [ 'dataListClass' => ManyManyThroughList::class, 'eagerloadedDataClass' => ValidatedObject::class, - $rows, + 'rows' => $rows, 'filter' => [ 'ID' => [1, 2], ], @@ -429,9 +424,9 @@ public function provideFilter(): array ]; } - public function provideFilterWithSearchFilters() + public static function provideFilterWithSearchFilters() { - $rows = $this->getBasicRecordRows(); + $rows = EagerLoadedListTest::getBasicRecordRows(); $scenarios = [ // exact match filter tests 'exact match - negate' => [ @@ -555,12 +550,10 @@ public function provideFilterWithSearchFilters() return $scenarios; } - /** - * @dataProvider provideFilterAnyWithSearchFilters - */ - public function testFilterAnyWithSearchfilters(array $filter, array $expectedIDs): void + #[DataProvider('provideFilterAnyWithSearchFilters')] + public function testFilterAnyWithSearchfilters(array $filter, array $expected): void { - $rows = $this->getBasicRecordRows(); + $rows = EagerLoadedListTest::getBasicRecordRows(); $list = new EagerLoadedList(ValidatedObject::class, DataList::class); foreach ($rows as $row) { $list->addRow($row); @@ -569,13 +562,13 @@ public function testFilterAnyWithSearchfilters(array $filter, array $expectedIDs // Validate that the unfiltered list still has all records, and the filtered list has the expected amount $this->assertCount(count($rows), $list); - $this->assertCount(count($expectedIDs), $filteredList); + $this->assertCount(count($expected), $filteredList); // Validate that the filtered list has the CORRECT records $this->iterate($list, $rows, array_column($rows, 'ID')); } - public function provideFilterAnyWithSearchFilters() + public static function provideFilterAnyWithSearchFilters() { return [ // test a couple of search filters @@ -618,12 +611,12 @@ public function provideFilterAnyWithSearchFilters() ]; } - public function provideExcludeWithSearchfilters() + public static function provideExcludeWithSearchfilters() { // If it's included in the filter test, then it's excluded in the exclude test, // so we can just use the same scenarios and reverse the expected results. - $rows = $this->getBasicRecordRows(); - $scenarios = $this->provideFilterWithSearchfilters(); + $rows = EagerLoadedListTest::getBasicRecordRows(); + $scenarios = EagerLoadedListTest::provideFilterWithSearchfilters(); foreach ($scenarios as $name => $scenario) { $kept = []; $excluded = []; @@ -645,12 +638,10 @@ public function provideExcludeWithSearchfilters() return $scenarios; } - /** - * @dataProvider provideExcludeWithSearchfilters - */ - public function testExcludeWithSearchfilters(array $filter, array $expectedIDs): void + #[DataProvider('provideExcludeWithSearchfilters')] + public function testExcludeWithSearchfilters(array $filter, array $expected): void { - $rows = $this->getBasicRecordRows(); + $rows = EagerLoadedListTest::getBasicRecordRows(); $list = new EagerLoadedList(ValidatedObject::class, DataList::class); foreach ($rows as $row) { $list->addRow($row); @@ -659,18 +650,18 @@ public function testExcludeWithSearchfilters(array $filter, array $expectedIDs): // Validate that the unfiltered list still has all records, and the filtered list has the expected amount $this->assertCount(count($rows), $list); - $this->assertCount(count($expectedIDs), $filteredList); + $this->assertCount(count($expected), $filteredList); // Validate that the filtered list has the CORRECT records $this->iterate($list, $rows, array_column($rows, 'ID')); } - public function provideExcludeAnyWithSearchfilters() + public static function provideExcludeAnyWithSearchfilters() { // If it's included in the filterAny test, then it's excluded in the excludeAny test, // so we can just use the same scenarios and reverse the expected results. - $rows = $this->getBasicRecordRows(); - $scenarios = $this->provideFilterAnyWithSearchfilters(); + $rows = EagerLoadedListTest::getBasicRecordRows(); + $scenarios = EagerLoadedListTest::provideFilterAnyWithSearchfilters(); foreach ($scenarios as $name => $scenario) { $kept = []; $excluded = []; @@ -687,12 +678,10 @@ public function provideExcludeAnyWithSearchfilters() return $scenarios; } - /** - * @dataProvider provideExcludeAnyWithSearchfilters - */ - public function testExcludeAnyWithSearchfilters(array $filter, array $expectedIDs): void + #[DataProvider('provideExcludeAnyWithSearchfilters')] + public function testExcludeAnyWithSearchfilters(array $filter, array $expected): void { - $rows = $this->getBasicRecordRows(); + $rows = EagerLoadedListTest::getBasicRecordRows(); $list = new EagerLoadedList(ValidatedObject::class, DataList::class); foreach ($rows as $row) { $list->addRow($row); @@ -701,7 +690,7 @@ public function testExcludeAnyWithSearchfilters(array $filter, array $expectedID // Validate that the unfiltered list still has all records, and the filtered list has the expected amount $this->assertCount(count($rows), $list); - $this->assertCount(count($expectedIDs), $filteredList); + $this->assertCount(count($expected), $filteredList); // Validate that the filtered list has the CORRECT records $this->iterate($list, $rows, array_column($rows, 'ID')); @@ -725,9 +714,7 @@ public function testFilterByRelationColumn() $list->filter(['Captain.ShirtNumber' => 'anything']); } - /** - * @dataProvider provideFilterByWrongNumArgs - */ + #[DataProvider('provideFilterByWrongNumArgs')] public function testFilterByWrongNumArgs(...$args) { $list = new EagerLoadedList(ValidatedObject::class, DataList::class); @@ -737,7 +724,7 @@ public function testFilterByWrongNumArgs(...$args) $list->filter(...$args); } - public function provideFilterByWrongNumArgs() + public static function provideFilterByWrongNumArgs() { return [ 0 => [], @@ -745,9 +732,7 @@ public function provideFilterByWrongNumArgs() ]; } - /** - * @dataProvider provideLimitAndOffset - */ + #[DataProvider('provideLimitAndOffset')] public function testLimitAndOffset($length, $offset, $expectedCount, $expectException = false) { $list = $this->getListWithRecords(TeamComment::class); @@ -768,7 +753,7 @@ public function testLimitAndOffset($length, $offset, $expectedCount, $expectExce $this->assertCount($expectedCount, $list->limit($length, $offset)->toArray()); } - public function provideLimitAndOffset(): array + public static function provideLimitAndOffset(): array { return [ 'no limit' => [null, 0, 3], @@ -1127,9 +1112,7 @@ public function testSortByRelation() $list = $list->sort('Team.Title', 'ASC'); } - /** - * @dataProvider provideSortInvalidParameters - */ + #[DataProvider('provideSortInvalidParameters')] public function testSortInvalidParameters(string $sort, string $type): void { if ($type === 'valid') { @@ -1162,7 +1145,7 @@ public function testSortInvalidParameters(string $sort, string $type): void /** * @see DataListTest::provideRawSqlSortException() */ - public function provideSortInvalidParameters(): array + public static function provideSortInvalidParameters(): array { return [ ['Title', 'valid'], @@ -1189,9 +1172,7 @@ public function provideSortInvalidParameters(): array ]; } - /** - * @dataProvider provideSortDirectionValidationTwoArgs - */ + #[DataProvider('provideSortDirectionValidationTwoArgs')] public function testSortDirectionValidationTwoArgs(string $direction, string $type): void { if ($type === 'valid') { @@ -1203,7 +1184,7 @@ public function testSortDirectionValidationTwoArgs(string $direction, string $ty $this->getListWithRecords(Team::class)->sort('Title', $direction)->column('ID'); } - public function provideSortDirectionValidationTwoArgs(): array + public static function provideSortDirectionValidationTwoArgs(): array { return [ ['ASC', 'valid'], @@ -1216,9 +1197,8 @@ public function provideSortDirectionValidationTwoArgs(): array /** * Test passing scalar values to sort() - * - * @dataProvider provideSortScalarValues */ + #[DataProvider('provideSortScalarValues')] public function testSortScalarValues(mixed $emtpyValue, string $type): void { $this->assertSame(['Subteam 1'], $this->getListWithRecords(Team::class)->limit(1)->column('Title')); @@ -1236,7 +1216,7 @@ public function testSortScalarValues(mixed $emtpyValue, string $type): void $this->assertSame(['Subteam 1'], $list->limit(1)->column('Title')); } - public function provideSortScalarValues(): array + public static function provideSortScalarValues(): array { return [ ['', 'empty-scalar'], @@ -1261,7 +1241,7 @@ public function testSortNull(): void $this->assertSame($order, $list->column('ID')); } - public function provideSortMatchesDataList() + public static function provideSortMatchesDataList() { // These will be used to make fixtures // We don't use a fixtures yaml file here because we want a full DataList of only @@ -1300,9 +1280,7 @@ public function provideSortMatchesDataList() return $scenarios; } - /** - * @dataProvider provideSortMatchesDataList - */ + #[DataProvider('provideSortMatchesDataList')] public function testSortMatchesDataList(string $sortDir, string $field, array $values) { // Use explicit per-scenario fixtures @@ -1500,7 +1478,7 @@ public function testFilterAnyAggregate() $list->filterAny(['Players.Count()' => 2]); } - public function provideCantFilterByRelation() + public static function provideCantFilterByRelation() { return [ 'many_many' => [ @@ -1518,9 +1496,7 @@ public function provideCantFilterByRelation() ]; } - /** - * @dataProvider provideCantFilterByRelation - */ + #[DataProvider('provideCantFilterByRelation')] public function testCantFilterByRelation(string $column) { // Many to many @@ -1530,9 +1506,7 @@ public function testCantFilterByRelation(string $column) $list->filter($column, ['Captain', 'Captain 2']); } - /** - * @dataProvider provideFilterByNull - */ + #[DataProvider('provideFilterByNull')] public function testFilterByNull(string $filterMethod, array $filter, array $expected) { // Force DataObjectTest_Fan/fan5::Email to empty string @@ -1544,7 +1518,7 @@ public function testFilterByNull(string $filterMethod, array $filter, array $exp $this->assertListEquals($expected, $filteredList); } - public function provideFilterByNull() + public static function provideFilterByNull() { return [ 'Filter by null email' => [ @@ -1802,8 +1776,8 @@ public function testMultipleExcludeArraysMultipleMatchesOneMiss() /** * Test that if an exclude() is applied to a filter(), the filter() is still preserved. - * @dataProvider provideExcludeOnFilter */ + #[DataProvider('provideExcludeOnFilter')] public function testExcludeOnFilter(array $filter, array $exclude, array $expected) { $list = $this->getListWithRecords(TeamComment::class); @@ -1812,7 +1786,7 @@ public function testExcludeOnFilter(array $filter, array $exclude, array $expect $this->assertListEquals($expected, $list->sort('Name')); } - public function provideExcludeOnFilter() + public static function provideExcludeOnFilter() { return [ [ @@ -2092,10 +2066,8 @@ public function testOffsetUnset() $list->offsetUnset(0); } - /** - * @dataProvider provideRelation - */ - public function testRelation(string $parentClass, string $relation, ?array $expected) + #[DataProvider('provideRelation')] + public function testRelation(string $parentClass, string $relation, ?array $expected, array $eagerLoaded) { $relationList = $this->getListWithRecords($parentClass)->relation($relation); if ($expected === null) { @@ -2106,9 +2078,7 @@ public function testRelation(string $parentClass, string $relation, ?array $expe } } - /** - * @dataProvider provideRelation - */ + #[DataProvider('provideRelation')] public function testRelationEagerLoaded(string $parentClass, string $relation, ?array $expected, array $eagerLoaded) { // Get an EagerLoadedList and add the relation data to it @@ -2139,7 +2109,7 @@ public function testRelationEagerLoaded(string $parentClass, string $relation, ? } } - public function provideRelation() + public static function provideRelation() { return [ 'many_many' => [ @@ -2150,7 +2120,7 @@ public function provideRelation() ['Title' => 'Test 2'], ['Title' => 'Test 3'], ], - 'eagerloaded' => [ + 'eagerLoaded' => [ 'test1' => [ ['class' => RelationChildSecond::class, 'fixture' => 'test1', 'Title' => 'Test 1'], ['class' => RelationChildSecond::class, 'fixture' => 'test2', 'Title' => 'Test 2'], @@ -2167,7 +2137,7 @@ public function provideRelation() 'expected' => [ ['Title' => 'Subteam 1'], ], - 'eagerloaded' => [ + 'eagerLoaded' => [ 'team1' => [ ['class' => SubTeam::class, 'fixture' => 'subteam1', 'Title' => 'Subteam 1'], ], @@ -2178,7 +2148,7 @@ public function provideRelation() 'parentClass' => DataObjectTest\Company::class, 'relation' => 'Owner', 'expected' => null, - 'eagerloaded' => [ + 'eagerLoaded' => [ 'company1' => [ 'class' => Player::class, 'fixture' => 'player1', 'Title' => 'Player 1', ], @@ -2190,9 +2160,7 @@ public function provideRelation() ]; } - /** - * @dataProvider provideCreateDataObject - */ + #[DataProvider('provideCreateDataObject')] public function testCreateDataObject(string $dataClass, string $realClass, array $row) { $list = new EagerLoadedList($dataClass, DataList::class); @@ -2214,7 +2182,7 @@ public function testCreateDataObject(string $dataClass, string $realClass, array } } - public function provideCreateDataObject() + public static function provideCreateDataObject() { return [ 'no ClassName' => [ @@ -2314,9 +2282,7 @@ public function testGetExtraDataBadID() $list->getExtraData('Teams', 'abc'); } - /** - * @dataProvider provideGetExtraDataBadListType - */ + #[DataProvider('provideGetExtraDataBadListType')] public function testGetExtraDataBadListType(string $listClass) { $list = new EagerLoadedList(Player::class, $listClass, 99999); @@ -2325,7 +2291,7 @@ public function testGetExtraDataBadListType(string $listClass) $list->getExtraData('Teams', 1); } - public function provideGetExtraDataBadListType() + public static function provideGetExtraDataBadListType() { return [ [HasManyList::class], diff --git a/tests/php/ORM/Filters/EndsWithFilterTest.php b/tests/php/ORM/Filters/EndsWithFilterTest.php index d8825d26c4c..0adec36ae87 100644 --- a/tests/php/ORM/Filters/EndsWithFilterTest.php +++ b/tests/php/ORM/Filters/EndsWithFilterTest.php @@ -6,155 +6,156 @@ use SilverStripe\ORM\Filters\EndsWithFilter; use SilverStripe\View\ArrayData; use SilverStripe\ORM\Filters\SearchFilter; +use PHPUnit\Framework\Attributes\DataProvider; class EndsWithFilterTest extends SapphireTest { - public function provideMatches() + public static function provideMatches() { $scenarios = [ // without modifiers 'null ends with null' => [ 'filterValue' => null, - 'objValue' => null, + 'matchValue' => null, 'modifiers' => [], 'matches' => true, ], 'empty ends with null' => [ 'filterValue' => null, - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => true, ], 'null ends with empty' => [ 'filterValue' => '', - 'objValue' => null, + 'matchValue' => null, 'modifiers' => [], 'matches' => true, ], 'empty ends with empty' => [ 'filterValue' => '', - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => true, ], 'empty ends with false' => [ 'filterValue' => false, - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => true, ], 'true doesnt end with empty' => [ 'filterValue' => true, - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => false, ], 'false doesnt end with empty' => [ 'filterValue' => '', - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => false, ], 'true doesnt end with empty' => [ 'filterValue' => '', - 'objValue' => true, + 'matchValue' => true, 'modifiers' => [], 'matches' => false, ], 'null ends with false' => [ 'filterValue' => false, - 'objValue' => null, + 'matchValue' => null, 'modifiers' => [], 'matches' => true, ], 'false doesnt end with null' => [ 'filterValue' => null, - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => false, ], 'false doesnt end with true' => [ 'filterValue' => true, - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => false, ], 'true doesnt end with false' => [ 'filterValue' => false, - 'objValue' => true, + 'matchValue' => true, 'modifiers' => [], 'matches' => false, ], 'false doesnt end with false' => [ 'filterValue' => false, - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => false, ], 'true doesnt end with true' => [ 'filterValue' => true, - 'objValue' => true, + 'matchValue' => true, 'modifiers' => [], 'matches' => false, ], 'number is cast to string' => [ 'filterValue' => 1, - 'objValue' => '1', + 'matchValue' => '1', 'modifiers' => [], 'matches' => true, ], '1 ends with 1' => [ 'filterValue' => 1, - 'objValue' => 1, + 'matchValue' => 1, 'modifiers' => [], 'matches' => true, ], '100 doesnt end with 1' => [ 'filterValue' => '1', - 'objValue' => 100, + 'matchValue' => 100, 'modifiers' => [], 'matches' => false, ], '100 ends with 0' => [ 'filterValue' => '0', - 'objValue' => 100, + 'matchValue' => 100, 'modifiers' => [], 'matches' => true, ], '100 still ends with 0' => [ 'filterValue' => 0, - 'objValue' => 100, + 'matchValue' => 100, 'modifiers' => [], 'matches' => true, ], 'SomeValue ends with SomeValue' => [ 'filterValue' => 'SomeValue', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => true, ], 'SomeValue doesnt end with somevalue' => [ 'filterValue' => 'somevalue', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => null, ], 'SomeValue doesnt end with meVal' => [ 'filterValue' => 'meVal', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => false, ], 'SomeValue ends with Value' => [ 'filterValue' => 'Value', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => true, ], 'SomeValue doesnt with vAlUe' => [ 'filterValue' => 'vAlUe', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => null, ], @@ -180,19 +181,19 @@ public function provideMatches() // Some multi-value tests [ 'filterValue' => [123, 'somevalue', 'abc'], - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => null, ], [ 'filterValue' => [123, 'Value', 'abc'], - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => [123, 'meVal', 'abc'], - 'objValue' => 'Some', + 'matchValue' => 'Some', 'modifiers' => [], 'matches' => false, ], @@ -200,38 +201,38 @@ public function provideMatches() // We're testing this scenario because ArrayList might contain arbitrary values [ 'filterValue' => new ArrayData(['SomeField' => 'some value']), - 'objValue' => new ArrayData(['SomeField' => 'some value']), + 'matchValue' => new ArrayData(['SomeField' => 'some value']), 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => new ArrayData(['SomeField' => 'SoMe VaLuE']), - 'objValue' => new ArrayData(['SomeField' => 'some value']), + 'matchValue' => new ArrayData(['SomeField' => 'some value']), 'modifiers' => [], 'matches' => true, ], // case insensitive [ 'filterValue' => 'somevalue', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => true, ], [ 'filterValue' => 'vAlUe', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => true, ], [ 'filterValue' => 'meval', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => false, ], [ 'filterValue' => 'different', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => false, ], @@ -252,9 +253,7 @@ public function provideMatches() return $scenarios; } - /** - * @dataProvider provideMatches - */ + #[DataProvider('provideMatches')] public function testMatches(mixed $filterValue, mixed $matchValue, array $modifiers, ?bool $matches) { // Test with explicit default case sensitivity rather than relying on the collation, so that database diff --git a/tests/php/ORM/Filters/ExactMatchFilterTest.php b/tests/php/ORM/Filters/ExactMatchFilterTest.php index 61cf04d42df..42c4c4c76d9 100644 --- a/tests/php/ORM/Filters/ExactMatchFilterTest.php +++ b/tests/php/ORM/Filters/ExactMatchFilterTest.php @@ -10,6 +10,7 @@ use SilverStripe\ORM\DataList; use SilverStripe\View\ArrayData; use SilverStripe\ORM\Filters\SearchFilter; +use PHPUnit\Framework\Attributes\DataProvider; class ExactMatchFilterTest extends SapphireTest { @@ -20,9 +21,7 @@ class ExactMatchFilterTest extends SapphireTest Project::class, ]; - /** - * @dataProvider provideUsePlaceholders - */ + #[DataProvider('provideUsePlaceholders')] public function testUsePlaceholders(?bool $expectedID, ?bool $expectedTitle, bool $config, callable $fn): void { Config::modify()->set(DataList::class, 'use_placeholders_for_integer_ids', $config); @@ -31,7 +30,7 @@ public function testUsePlaceholders(?bool $expectedID, ?bool $expectedTitle, boo $this->assertSame($expectedTitle, $titleQueryUsesPlaceholders); } - public function provideUsePlaceholders(): array + public static function provideUsePlaceholders(): array { $ids = [1, 2, 3]; $taskTitles = array_map(fn($i) => "Task $i", $ids); @@ -96,115 +95,115 @@ private function usesPlaceholders(callable $fn): array return [$idQueryUsesPlaceholders, $titleQueryUsesPlaceholders]; } - public function provideMatches() + public static function provideMatches() { $scenarios = [ // without modifiers [ 'filterValue' => null, - 'objValue' => null, + 'matchValue' => null, 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => null, - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => false, ], [ 'filterValue' => '', - 'objValue' => null, + 'matchValue' => null, 'modifiers' => [], 'matches' => false, ], [ 'filterValue' => '', - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => false, - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => true, - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => false, ], [ 'filterValue' => '', - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => '', - 'objValue' => true, + 'matchValue' => true, 'modifiers' => [], 'matches' => false, ], [ 'filterValue' => false, - 'objValue' => null, + 'matchValue' => null, 'modifiers' => [], 'matches' => false, ], [ 'filterValue' => null, - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => false, ], [ 'filterValue' => true, - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => false, ], [ 'filterValue' => false, - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => true, - 'objValue' => true, + 'matchValue' => true, 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => 'SomeValue', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => 'somevalue', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => null, ], [ 'filterValue' => 'SomeValue', - 'objValue' => 'Some', + 'matchValue' => 'Some', 'modifiers' => [], 'matches' => false, ], [ 'filterValue' => 1, - 'objValue' => '1', + 'matchValue' => '1', 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => 1, - 'objValue' => 1, + 'matchValue' => 1, 'modifiers' => [], 'matches' => true, ], @@ -230,25 +229,25 @@ public function provideMatches() // Some multi-value tests [ 'filterValue' => [123, 'somevalue', 'abc'], - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => null, ], [ 'filterValue' => [123, 'SomeValue', 'abc'], - 'objValue' => 'Some', + 'matchValue' => 'Some', 'modifiers' => [], 'matches' => false, ], [ 'filterValue' => [1, 2, 3], - 'objValue' => '1', + 'matchValue' => '1', 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => [4, 5, 6], - 'objValue' => 1, + 'matchValue' => 1, 'modifiers' => [], 'matches' => false, ], @@ -257,27 +256,27 @@ public function provideMatches() // anything as its value [ 'filterValue' => new ArrayData(['SomeField' => 'some value']), - 'objValue' => new ArrayData(['SomeField' => 'some value']), + 'matchValue' => new ArrayData(['SomeField' => 'some value']), 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => new ArrayData(['SomeField' => 'SoMe VaLuE']), - 'objValue' => new ArrayData(['SomeField' => 'some value']), + 'matchValue' => new ArrayData(['SomeField' => 'some value']), 'modifiers' => [], 'matches' => false, ], // case insensitive [ 'filterValue' => 'somevalue', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => true, ], // doesn't do partial matching even when case insensitive [ 'filterValue' => 'some', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => false, ], @@ -298,10 +297,8 @@ public function provideMatches() return $scenarios; } - /** - * @dataProvider provideMatches - */ - public function testMatches(mixed $filterValue, mixed $objValue, array $modifiers, ?bool $matches) + #[DataProvider('provideMatches')] + public function testMatches(mixed $filterValue, mixed $matchValue, array $modifiers, ?bool $matches) { // Test with explicit default case sensitivity rather than relying on the collation, so that database // settings don't interfere with the test @@ -318,7 +315,7 @@ public function testMatches(mixed $filterValue, mixed $objValue, array $modifier $filter = new ExactMatchFilter(); $filter->setValue($filterValue); $filter->setModifiers($modifiers); - $this->assertSame($matches ?? $nullMatch, $filter->matches($objValue)); + $this->assertSame($matches ?? $nullMatch, $filter->matches($matchValue)); } } } diff --git a/tests/php/ORM/Filters/GreaterThanFilterTest.php b/tests/php/ORM/Filters/GreaterThanFilterTest.php index 6a7bcf284cc..1b2cb92c286 100644 --- a/tests/php/ORM/Filters/GreaterThanFilterTest.php +++ b/tests/php/ORM/Filters/GreaterThanFilterTest.php @@ -5,11 +5,12 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\Filters\GreaterThanFilter; use SilverStripe\View\ArrayData; +use PHPUnit\Framework\Attributes\DataProvider; class GreaterThanFilterTest extends SapphireTest { - public function provideMatches() + public static function provideMatches() { $scenarios = [ // without modifiers @@ -212,9 +213,7 @@ public function provideMatches() return $scenarios; } - /** - * @dataProvider provideMatches - */ + #[DataProvider('provideMatches')] public function testMatches(mixed $filterValue, mixed $matchValue, array $modifiers, bool $matches) { $filter = new GreaterThanFilter(); diff --git a/tests/php/ORM/Filters/GreaterThanOrEqualFilterTest.php b/tests/php/ORM/Filters/GreaterThanOrEqualFilterTest.php index c93f3a8a9e0..d32668c33bb 100644 --- a/tests/php/ORM/Filters/GreaterThanOrEqualFilterTest.php +++ b/tests/php/ORM/Filters/GreaterThanOrEqualFilterTest.php @@ -5,11 +5,12 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\Filters\GreaterThanOrEqualFilter; use SilverStripe\View\ArrayData; +use PHPUnit\Framework\Attributes\DataProvider; class GreaterThanOrEqualFilterTest extends SapphireTest { - public function provideMatches() + public static function provideMatches() { $scenarios = [ // without modifiers @@ -212,9 +213,7 @@ public function provideMatches() return $scenarios; } - /** - * @dataProvider provideMatches - */ + #[DataProvider('provideMatches')] public function testMatches(mixed $filterValue, mixed $matchValue, array $modifiers, bool $matches) { $filter = new GreaterThanOrEqualFilter(); diff --git a/tests/php/ORM/Filters/LessThanFilterTest.php b/tests/php/ORM/Filters/LessThanFilterTest.php index ac8f5fa4e1f..701af0eddfc 100644 --- a/tests/php/ORM/Filters/LessThanFilterTest.php +++ b/tests/php/ORM/Filters/LessThanFilterTest.php @@ -5,11 +5,12 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\Filters\LessThanFilter; use SilverStripe\View\ArrayData; +use PHPUnit\Framework\Attributes\DataProvider; class LessThanFilterTest extends SapphireTest { - public function provideMatches() + public static function provideMatches() { $scenarios = [ // without modifiers @@ -212,9 +213,7 @@ public function provideMatches() return $scenarios; } - /** - * @dataProvider provideMatches - */ + #[DataProvider('provideMatches')] public function testMatches(mixed $filterValue, mixed $matchValue, array $modifiers, bool $matches) { $filter = new LessThanFilter(); diff --git a/tests/php/ORM/Filters/LessThanOrEqualFilterTest.php b/tests/php/ORM/Filters/LessThanOrEqualFilterTest.php index 30a0f3078a1..961eb22e6b4 100644 --- a/tests/php/ORM/Filters/LessThanOrEqualFilterTest.php +++ b/tests/php/ORM/Filters/LessThanOrEqualFilterTest.php @@ -5,11 +5,12 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\Filters\LessThanOrEqualFilter; use SilverStripe\View\ArrayData; +use PHPUnit\Framework\Attributes\DataProvider; class LessThanOrEqualFilterTest extends SapphireTest { - public function provideMatches() + public static function provideMatches() { $scenarios = [ // without modifiers @@ -212,9 +213,7 @@ public function provideMatches() return $scenarios; } - /** - * @dataProvider provideMatches - */ + #[DataProvider('provideMatches')] public function testMatches(mixed $filterValue, mixed $matchValue, array $modifiers, bool $matches) { $filter = new LessThanOrEqualFilter(); diff --git a/tests/php/ORM/Filters/PartialMatchFilterTest.php b/tests/php/ORM/Filters/PartialMatchFilterTest.php index f4ad899427d..726592272dc 100644 --- a/tests/php/ORM/Filters/PartialMatchFilterTest.php +++ b/tests/php/ORM/Filters/PartialMatchFilterTest.php @@ -6,149 +6,150 @@ use SilverStripe\ORM\Filters\PartialMatchFilter; use SilverStripe\View\ArrayData; use SilverStripe\ORM\Filters\SearchFilter; +use PHPUnit\Framework\Attributes\DataProvider; class PartialMatchFilterTest extends SapphireTest { - public function provideMatches() + public static function provideMatches() { $scenarios = [ // without modifiers 'null partially matches null' => [ 'filterValue' => null, - 'objValue' => null, + 'matchValue' => null, 'modifiers' => [], 'matches' => true, ], 'null partially matches empty' => [ 'filterValue' => null, - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => true, ], 'empty partially matches null' => [ 'filterValue' => '', - 'objValue' => null, + 'matchValue' => null, 'modifiers' => [], 'matches' => true, ], 'empty partially matches empty' => [ 'filterValue' => '', - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => true, ], 'false partially matches empty' => [ 'filterValue' => false, - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => true, ], 'true doesnt partially match empty' => [ 'filterValue' => true, - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => false, ], 'empty partially matches false' => [ 'filterValue' => '', - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => true, ], 'empty doesnt partially match true' => [ 'filterValue' => '', - 'objValue' => true, + 'matchValue' => true, 'modifiers' => [], 'matches' => false, ], 'false partially matches null' => [ 'filterValue' => false, - 'objValue' => null, + 'matchValue' => null, 'modifiers' => [], 'matches' => true, ], 'null partially matches false' => [ 'filterValue' => null, - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => true, ], 'true doesnt partially match false' => [ 'filterValue' => true, - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => false, ], 'false doesnt partially match true' => [ 'filterValue' => false, - 'objValue' => true, + 'matchValue' => true, 'modifiers' => [], 'matches' => false, ], 'false partially matches false' => [ 'filterValue' => false, - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => true, ], 'true partially matches true' => [ 'filterValue' => true, - 'objValue' => true, + 'matchValue' => true, 'modifiers' => [], 'matches' => true, ], 'number is cast to string' => [ 'filterValue' => 1, - 'objValue' => '1', + 'matchValue' => '1', 'modifiers' => [], 'matches' => true, ], 'numeric match' => [ 'filterValue' => 1, - 'objValue' => 1, + 'matchValue' => 1, 'modifiers' => [], 'matches' => true, ], 'partial numeric match' => [ 'filterValue' => '1', - 'objValue' => 100, + 'matchValue' => 100, 'modifiers' => [], 'matches' => true, ], 'partial numeric match2' => [ 'filterValue' => 1, - 'objValue' => 100, + 'matchValue' => 100, 'modifiers' => [], 'matches' => true, ], 'partial numeric match3' => [ 'filterValue' => 0, - 'objValue' => 100, + 'matchValue' => 100, 'modifiers' => [], 'matches' => true, ], 'case sensitive match' => [ 'filterValue' => 'SomeValue', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => true, ], 'case sensitive mismatch' => [ 'filterValue' => 'somevalue', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => null, ], 'case sensitive partial match' => [ 'filterValue' => 'meVal', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => true, ], 'case sensitive partial mismatch' => [ 'filterValue' => 'meval', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => null, ], @@ -174,25 +175,25 @@ public function provideMatches() // Some multi-value tests [ 'filterValue' => [123, 'somevalue', 'abc'], - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => null, ], [ 'filterValue' => [123, 'meVal', 'abc'], - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => [123, 'meval', 'abc'], - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => null, ], [ 'filterValue' => [4, 5, 6], - 'objValue' => 1, + 'matchValue' => 1, 'modifiers' => [], 'matches' => false, ], @@ -200,38 +201,38 @@ public function provideMatches() // We're testing this scenario because ArrayList might contain arbitrary values [ 'filterValue' => new ArrayData(['SomeField' => 'some value']), - 'objValue' => new ArrayData(['SomeField' => 'some value']), + 'matchValue' => new ArrayData(['SomeField' => 'some value']), 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => new ArrayData(['SomeField' => 'SoMe VaLuE']), - 'objValue' => new ArrayData(['SomeField' => 'some value']), + 'matchValue' => new ArrayData(['SomeField' => 'some value']), 'modifiers' => [], 'matches' => true, ], // case insensitive [ 'filterValue' => 'somevalue', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => true, ], [ 'filterValue' => 'some', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => true, ], [ 'filterValue' => 'meval', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => true, ], [ 'filterValue' => 'different', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => false, ], @@ -252,10 +253,8 @@ public function provideMatches() return $scenarios; } - /** - * @dataProvider provideMatches - */ - public function testMatches(mixed $filterValue, mixed $objValue, array $modifiers, ?bool $matches) + #[DataProvider('provideMatches')] + public function testMatches(mixed $filterValue, mixed $matchValue, array $modifiers, ?bool $matches) { // Test with explicit default case sensitivity rather than relying on the collation, so that database // settings don't interfere with the test @@ -272,7 +271,7 @@ public function testMatches(mixed $filterValue, mixed $objValue, array $modifier $filter = new PartialMatchFilter(); $filter->setValue($filterValue); $filter->setModifiers($modifiers); - $this->assertSame($matches ?? $nullMatch, $filter->matches($objValue)); + $this->assertSame($matches ?? $nullMatch, $filter->matches($matchValue)); } } } diff --git a/tests/php/ORM/Filters/StartsWithFilterTest.php b/tests/php/ORM/Filters/StartsWithFilterTest.php index 855020f53a6..15832643ff5 100644 --- a/tests/php/ORM/Filters/StartsWithFilterTest.php +++ b/tests/php/ORM/Filters/StartsWithFilterTest.php @@ -6,155 +6,156 @@ use SilverStripe\ORM\Filters\StartsWithFilter; use SilverStripe\View\ArrayData; use SilverStripe\ORM\Filters\SearchFilter; +use PHPUnit\Framework\Attributes\DataProvider; class StartsWithFilterTest extends SapphireTest { - public function provideMatches() + public static function provideMatches() { $scenarios = [ // without modifiers 'null starts with null' => [ 'filterValue' => null, - 'objValue' => null, + 'matchValue' => null, 'modifiers' => [], 'matches' => true, ], 'empty starts with null' => [ 'filterValue' => null, - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => true, ], 'null starts with empty' => [ 'filterValue' => '', - 'objValue' => null, + 'matchValue' => null, 'modifiers' => [], 'matches' => true, ], 'empty starts with empty' => [ 'filterValue' => '', - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => true, ], 'empty starts with false' => [ 'filterValue' => false, - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => true, ], 'true doesnt start with empty' => [ 'filterValue' => true, - 'objValue' => '', + 'matchValue' => '', 'modifiers' => [], 'matches' => false, ], 'false doesnt start with empty' => [ 'filterValue' => '', - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => false, ], 'true doesnt start with empty' => [ 'filterValue' => '', - 'objValue' => true, + 'matchValue' => true, 'modifiers' => [], 'matches' => false, ], 'null starts with false' => [ 'filterValue' => false, - 'objValue' => null, + 'matchValue' => null, 'modifiers' => [], 'matches' => true, ], 'false doesnt start with null' => [ 'filterValue' => null, - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => false, ], 'false doesnt start with true' => [ 'filterValue' => true, - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => false, ], 'true doesnt start with false' => [ 'filterValue' => false, - 'objValue' => true, + 'matchValue' => true, 'modifiers' => [], 'matches' => false, ], 'false doesnt start with false' => [ 'filterValue' => false, - 'objValue' => false, + 'matchValue' => false, 'modifiers' => [], 'matches' => false, ], 'true doesnt start with true' => [ 'filterValue' => true, - 'objValue' => true, + 'matchValue' => true, 'modifiers' => [], 'matches' => false, ], 'number is cast to string' => [ 'filterValue' => 1, - 'objValue' => '1', + 'matchValue' => '1', 'modifiers' => [], 'matches' => true, ], '1 starts with 1' => [ 'filterValue' => 1, - 'objValue' => 1, + 'matchValue' => 1, 'modifiers' => [], 'matches' => true, ], '100 starts with 1' => [ 'filterValue' => '1', - 'objValue' => 100, + 'matchValue' => 100, 'modifiers' => [], 'matches' => true, ], '100 still starts with 1' => [ 'filterValue' => 1, - 'objValue' => 100, + 'matchValue' => 100, 'modifiers' => [], 'matches' => true, ], '100 doesnt start with 0' => [ 'filterValue' => 0, - 'objValue' => 100, + 'matchValue' => 100, 'modifiers' => [], 'matches' => false, ], 'SomeValue starts with SomeValue' => [ 'filterValue' => 'SomeValue', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => true, ], 'SomeValue doesnt start with somevalue' => [ 'filterValue' => 'somevalue', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => null, ], 'SomeValue doesnt start with meVal' => [ 'filterValue' => 'meVal', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => false, ], 'SomeValue starts with Some' => [ 'filterValue' => 'Some', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => true, ], 'SomeValue doesnt start with with sOmE' => [ 'filterValue' => 'sOmE', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => null, ], @@ -180,19 +181,19 @@ public function provideMatches() // Some multi-value tests [ 'filterValue' => [123, 'somevalue', 'abc'], - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => null, ], [ 'filterValue' => [123, 'Some', 'abc'], - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => [123, 'meVal', 'abc'], - 'objValue' => 'Some', + 'matchValue' => 'Some', 'modifiers' => [], 'matches' => false, ], @@ -200,38 +201,38 @@ public function provideMatches() // We're testing this scenario because ArrayList might contain arbitrary values [ 'filterValue' => new ArrayData(['SomeField' => 'some value']), - 'objValue' => new ArrayData(['SomeField' => 'some value']), + 'matchValue' => new ArrayData(['SomeField' => 'some value']), 'modifiers' => [], 'matches' => true, ], [ 'filterValue' => new ArrayData(['SomeField' => 'SoMe VaLuE']), - 'objValue' => new ArrayData(['SomeField' => 'some value']), + 'matchValue' => new ArrayData(['SomeField' => 'some value']), 'modifiers' => [], 'matches' => true, ], // case insensitive [ 'filterValue' => 'somevalue', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => true, ], [ 'filterValue' => 'sOmE', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => true, ], [ 'filterValue' => 'meval', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => false, ], [ 'filterValue' => 'different', - 'objValue' => 'SomeValue', + 'matchValue' => 'SomeValue', 'modifiers' => ['nocase'], 'matches' => false, ], @@ -252,9 +253,7 @@ public function provideMatches() return $scenarios; } - /** - * @dataProvider provideMatches - */ + #[DataProvider('provideMatches')] public function testMatches(mixed $filterValue, mixed $matchValue, array $modifiers, ?bool $matches) { // Test with explicit default case sensitivity rather than relying on the collation, so that database diff --git a/tests/php/ORM/HasManyListTest.php b/tests/php/ORM/HasManyListTest.php index 143412b1007..0a1e759daf3 100644 --- a/tests/php/ORM/HasManyListTest.php +++ b/tests/php/ORM/HasManyListTest.php @@ -10,6 +10,7 @@ use SilverStripe\ORM\Tests\HasManyListTest\Employee; use SilverStripe\Core\Config\Config; use SilverStripe\ORM\DataList; +use PHPUnit\Framework\Attributes\DataProvider; class HasManyListTest extends SapphireTest { @@ -192,9 +193,7 @@ public function testRemoveCallbackOnRemoveById() $this->assertEquals([$remove->ID], $removedIds); } - /** - * @dataProvider provideForForeignIDPlaceholders - */ + #[DataProvider('provideForForeignIDPlaceholders')] public function testForForeignIDPlaceholders(bool $config, bool $useInt, bool $expected): void { Config::modify()->set(DataList::class, 'use_placeholders_for_integer_ids', $config); @@ -214,7 +213,7 @@ public function testForForeignIDPlaceholders(bool $config, bool $useInt, bool $e $this->assertSame($expectedIDs, $newCommentsList->column('ID')); } - public function provideForForeignIDPlaceholders(): array + public static function provideForForeignIDPlaceholders(): array { return [ 'config false' => [ diff --git a/tests/php/ORM/HierarchyCachingTest.php b/tests/php/ORM/HierarchyCachingTest.php index 8070fbe26d7..6aa16c21d74 100644 --- a/tests/php/ORM/HierarchyCachingTest.php +++ b/tests/php/ORM/HierarchyCachingTest.php @@ -11,11 +11,12 @@ use SilverStripe\ORM\Tests\HierarchyTest\HideTestSubObject; use SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestObject; use SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject; +use PHPUnit\Framework\Attributes\DataProvider; /** * @internal Only test the right values are returned, not that the cache is actually used. */ -class HierachyCacheTest extends SapphireTest +class HierarchyCachingTest extends SapphireTest { protected static $fixture_file = 'HierarchyTest.yml'; @@ -43,7 +44,7 @@ public static function setUpBeforeClass(): void ); } - public function cacheNumChildrenDataProvider() + public static function cacheNumChildrenDataProvider() { return [ [TestObject::class, 'obj1', false, 0, 'childless object should have a numChildren of 0'], @@ -60,9 +61,7 @@ public function cacheNumChildrenDataProvider() } - /** - * @dataProvider cacheNumChildrenDataProvider - */ + #[DataProvider('cacheNumChildrenDataProvider')] public function testNumChildrenCache($className, $identifier, $cache, $expected, $message) { $node = $this->objFromFixture($className, $identifier); @@ -78,7 +77,7 @@ public function testNumChildrenCache($className, $identifier, $cache, $expected, } } - public function prepopulateCacheNumChildrenDataProvider() + public static function prepopulateCacheNumChildrenDataProvider() { return [ [ @@ -132,9 +131,7 @@ public function prepopulateCacheNumChildrenDataProvider() ]; } - /** - * @dataProvider prepopulateCacheNumChildrenDataProvider - */ + #[DataProvider('prepopulateCacheNumChildrenDataProvider')] public function testPrepopulatedNumChildrenCache( $className, $idList, diff --git a/tests/php/ORM/ListDecoratorTest.php b/tests/php/ORM/ListDecoratorTest.php index e0c011a9009..898f4c73d6f 100644 --- a/tests/php/ORM/ListDecoratorTest.php +++ b/tests/php/ORM/ListDecoratorTest.php @@ -9,6 +9,7 @@ use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ListDecorator; use SilverStripe\ORM\SS_List; +use PHPUnit\Framework\Attributes\DataProvider; /** * This test class is testing that ListDecorator correctly proxies its calls through to the underlying SS_List @@ -30,7 +31,9 @@ protected function setUp(): void parent::setUp(); $this->list = $this->createMock(ArrayList::class); - $this->decorator = $this->getMockForAbstractClass(ListDecorator::class, [$this->list]); + // ListDecorator is an abstract class so cannot be instantiated, though has no abstract methods + $this->decorator = new class ($this->list) extends ListDecorator { + }; } public function testGetIterator() @@ -54,8 +57,8 @@ public function testRemove() /** * @param array $input - * @dataProvider filterProvider */ + #[DataProvider('filterProvider')] public function testExclude($input) { $this->list->expects($this->once())->method('exclude')->with($input)->willReturn('mock'); @@ -64,8 +67,8 @@ public function testExclude($input) /** * @param array $input - * @dataProvider filterProvider */ + #[DataProvider('filterProvider')] public function testFilter($input) { $this->list->expects($this->once())->method('filter')->with($input)->willReturn('mock'); @@ -74,8 +77,8 @@ public function testFilter($input) /** * @param array $input - * @dataProvider filterProvider */ + #[DataProvider('filterProvider')] public function testFilterAny($input) { $this->list->expects($this->once())->method('filterAny')->with($input)->willReturn('mock'); @@ -84,8 +87,8 @@ public function testFilterAny($input) /** * @param array $input - * @dataProvider filterProvider */ + #[DataProvider('filterProvider')] public function testSort($input) { $this->list->expects($this->once())->method('sort')->with($input)->willReturn('mock'); @@ -95,7 +98,7 @@ public function testSort($input) /** * @return array[] */ - public function filterProvider() + public static function filterProvider() { return [ ['Name', 'Bob'], diff --git a/tests/php/ORM/ManyManyListTest.php b/tests/php/ORM/ManyManyListTest.php index f29856568bc..4191a7fa2df 100644 --- a/tests/php/ORM/ManyManyListTest.php +++ b/tests/php/ORM/ManyManyListTest.php @@ -14,6 +14,7 @@ use SilverStripe\ORM\Tests\ManyManyListTest\ExtraFieldsObject; use SilverStripe\ORM\Tests\ManyManyListTest\Product; use SilverStripe\ORM\DataList; +use PHPUnit\Framework\Attributes\DataProvider; class ManyManyListTest extends SapphireTest { @@ -617,9 +618,7 @@ public function testRemoveCallbackOnRemoveAll() $this->assertEquals(sort($remove), sort($removedIds)); } - /** - * @dataProvider provideForForeignIDPlaceholders - */ + #[DataProvider('provideForForeignIDPlaceholders')] public function testForForeignIDPlaceholders(bool $config, bool $useInt, bool $expected): void { Config::modify()->set(DataList::class, 'use_placeholders_for_integer_ids', $config); @@ -639,7 +638,7 @@ public function testForForeignIDPlaceholders(bool $config, bool $useInt, bool $e $this->assertEqualsCanonicalizing($expectedIDs, $newPlayersList->column('ID')); } - public function provideForForeignIDPlaceholders(): array + public static function provideForForeignIDPlaceholders(): array { return [ 'config false' => [ diff --git a/tests/php/ORM/ManyManyThroughListTest.php b/tests/php/ORM/ManyManyThroughListTest.php index 187e3023da2..7b3aacff004 100644 --- a/tests/php/ORM/ManyManyThroughListTest.php +++ b/tests/php/ORM/ManyManyThroughListTest.php @@ -16,6 +16,7 @@ use SilverStripe\ORM\Tests\ManyManyThroughListTest\FallbackLocale; use SilverStripe\ORM\Tests\ManyManyThroughListTest\TestObject; use SilverStripe\ORM\DataList; +use PHPUnit\Framework\Attributes\DataProvider; class ManyManyThroughListTest extends SapphireTest { @@ -96,8 +97,8 @@ public function testSelectJoin() /** * @param string $sort * @param array $expected - * @dataProvider sortingProvider */ + #[DataProvider('sortingProvider')] public function testSorting($sort, $expected) { /** @var ManyManyThroughListTest\TestObject $parent */ @@ -113,7 +114,7 @@ public function testSorting($sort, $expected) /** * @return array[] */ - public function sortingProvider() + public static function sortingProvider() { return [ 'nothing passed (default)' => [ @@ -163,7 +164,7 @@ public function sortingProvider() ]; } - public function provideAdd(): array + public static function provideAdd(): array { return [ [ @@ -181,9 +182,7 @@ public function provideAdd(): array ]; } - /** - * @dataProvider provideAdd - */ + #[DataProvider('provideAdd')] public function testAdd(string $parentClass, string $joinClass, string $joinProperty, string $relation) { $parent = $this->objFromFixture($parentClass, 'parent1'); @@ -207,7 +206,7 @@ public function testAdd(string $parentClass, string $joinClass, string $joinProp $this->assertEquals('new join record', $newItem->$joinProperty->Title); } - public function provideRemove(): array + public static function provideRemove(): array { return [ [ @@ -221,9 +220,7 @@ public function provideRemove(): array ]; } - /** - * @dataProvider provideRemove - */ + #[DataProvider('provideRemove')] public function testRemove(string $parentClass, string $relation) { $parent = $this->objFromFixture($parentClass, 'parent1'); @@ -554,9 +551,7 @@ public function testRemoveCallbackOnRemoveAll() $this->assertEquals(sort($remove), sort($removedIds)); } - /** - * @dataProvider provideForForeignIDPlaceholders - */ + #[DataProvider('provideForForeignIDPlaceholders')] public function testForForeignIDPlaceholders(bool $config, bool $useInt, bool $expected): void { Config::modify()->set(DataList::class, 'use_placeholders_for_integer_ids', $config); @@ -576,7 +571,7 @@ public function testForForeignIDPlaceholders(bool $config, bool $useInt, bool $e $this->assertEqualsCanonicalizing($expectedIDs, $newItemsList->column('ID')); } - public function provideForForeignIDPlaceholders(): array + public static function provideForForeignIDPlaceholders(): array { return [ 'config false' => [ diff --git a/tests/php/ORM/MarkedSetTest.php b/tests/php/ORM/MarkedSetTest.php index e2af6cffd55..e609a3aca38 100644 --- a/tests/php/ORM/MarkedSetTest.php +++ b/tests/php/ORM/MarkedSetTest.php @@ -72,9 +72,6 @@ public function testItemMarkingIsntRestrictedToSpecificInstance() $this->assertEquals(['Obj 2', 'Obj 2a', 'Obj 2b'], $expanded); } - /** - * @covers \SilverStripe\ORM\Hierarchy\MarkedSet::markChildren() - */ public function testMarkChildrenDoesntUnmarkPreviouslyMarked() { $obj3 = $this->objFromFixture(HierarchyTest\TestObject::class, 'obj3'); diff --git a/tests/php/ORM/MySQLDatabaseTest.php b/tests/php/ORM/MySQLDatabaseTest.php index 51461040e4c..f3313a4578d 100644 --- a/tests/php/ORM/MySQLDatabaseTest.php +++ b/tests/php/ORM/MySQLDatabaseTest.php @@ -10,6 +10,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\Connect\MySQLDatabase; use SilverStripe\ORM\Tests\MySQLSchemaManagerTest\MySQLDBDummy; +use PHPUnit\Framework\Attributes\DataProvider; class MySQLDatabaseTest extends SapphireTest { @@ -113,7 +114,7 @@ public function testAffectedRows() $this->assertEquals(1, DB::affected_rows()); } - public function provideSupportsCte() + public static function provideSupportsCte() { return [ // mysql unsupported @@ -204,9 +205,7 @@ public function provideSupportsCte() ]; } - /** - * @dataProvider provideSupportsCte - */ + #[DataProvider('provideSupportsCte')] public function testSupportsCte(string $version, bool $expected, bool $expectedRecursive) { $database = new MySQLDBDummy($version); diff --git a/tests/php/ORM/MySQLiConnectorTest.php b/tests/php/ORM/MySQLiConnectorTest.php index 8da8b65dd1b..3d7ac8d0a16 100644 --- a/tests/php/ORM/MySQLiConnectorTest.php +++ b/tests/php/ORM/MySQLiConnectorTest.php @@ -9,10 +9,10 @@ use SilverStripe\ORM\DB; use SilverStripe\ORM\Tests\MySQLiConnectorTest\MySQLiConnector; use SilverStripe\Tests\ORM\Utf8\Utf8TestHelper; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; -/** - * @requires extension mysqli - */ +#[RequiresPhpExtension('mysqli')] class MySQLiConnectorTest extends SapphireTest implements TestOnly { /** @var array project database settings configuration */ @@ -50,9 +50,7 @@ public function setUp(): void $this->config = $config; } - /** - * @dataProvider charsetProvider - */ + #[DataProvider('charsetProvider')] public function testConnectionCharsetControl($charset, $defaultCollation) { $connector = $this->getConnector($charset); @@ -69,9 +67,7 @@ public function testConnectionCharsetControl($charset, $defaultCollation) unset($cset, $connection, $connector, $config); } - /** - * @dataProvider charsetProvider - */ + #[DataProvider('charsetProvider')] public function testConnectionCollationControl($charset, $defaultCollation, $customCollation) { $connector = $this->getConnector($charset, $customCollation); @@ -107,7 +103,7 @@ public function testConnectionCollationControl($charset, $defaultCollation, $cus unset($cset, $connection, $connector, $config); } - public function charsetProvider() + public static function charsetProvider() { return [ ['ascii', 'ascii_general_ci', 'ascii_bin'], diff --git a/tests/php/ORM/PaginatedListTest.php b/tests/php/ORM/PaginatedListTest.php index 81959467a47..0f26f6fa91d 100644 --- a/tests/php/ORM/PaginatedListTest.php +++ b/tests/php/ORM/PaginatedListTest.php @@ -63,10 +63,10 @@ public function testSetPaginationFromQuery() $query = $this->getMockBuilder(SQLSelect::class)->getMock(); $query->expects($this->once()) ->method('getLimit') - ->will($this->returnValue(['limit' => 15, 'start' => 30])); + ->willReturn(['limit' => 15, 'start' => 30]); $query->expects($this->once()) ->method('unlimitedRowCount') - ->will($this->returnValue(100)); + ->willReturn(100); $list = new PaginatedList(new ArrayList()); $list->setPaginationFromQuery($query); diff --git a/tests/php/ORM/SQLSelectTest.php b/tests/php/ORM/SQLSelectTest.php index d915a676c29..3dccfc9933a 100755 --- a/tests/php/ORM/SQLSelectTest.php +++ b/tests/php/ORM/SQLSelectTest.php @@ -14,6 +14,7 @@ use SilverStripe\ORM\Connect\DatabaseException; use SilverStripe\ORM\Tests\SQLSelectTest\CteDatesObject; use SilverStripe\ORM\Tests\SQLSelectTest\CteRecursiveObject; +use PHPUnit\Framework\Attributes\DataProvider; class SQLSelectTest extends SapphireTest { @@ -74,7 +75,7 @@ public function testUnlimitedRowCount() } } - public function provideIsEmpty() + public static function provideIsEmpty() { return [ [ @@ -104,9 +105,7 @@ public function provideIsEmpty() ]; } - /** - * @dataProvider provideIsEmpty - */ + #[DataProvider('provideIsEmpty')] public function testIsEmpty(SQLSelect $query, $expected) { $this->assertSame($expected, $query->isEmpty()); @@ -118,7 +117,7 @@ public function testEmptyQueryReturnsNothing() $this->assertSQLEquals('', $query->sql($parameters)); } - public function provideSelectFrom() + public static function provideSelectFrom() { return [ [ @@ -140,9 +139,7 @@ public function provideSelectFrom() ]; } - /** - * @dataProvider provideSelectFrom - */ + #[DataProvider('provideSelectFrom')] public function testSelectFrom(array $from, string $expected) { $query = new SQLSelect(); @@ -818,7 +815,7 @@ public function testLimitSetFromClauseString() $this->assertEquals(10, $limit['start']); } - public function provideParameterisedJoinSQL() + public static function provideParameterisedJoinSQL() { return [ [ @@ -836,9 +833,7 @@ public function provideParameterisedJoinSQL() ]; } - /** - * @dataProvider provideParameterisedJoinSQL - */ + #[DataProvider('provideParameterisedJoinSQL')] public function testParameterisedJoinSQL($joinMethod, $joinType) { $query = new SQLSelect(); @@ -865,7 +860,7 @@ public function testParameterisedJoinSQL($joinMethod, $joinType) $query->execute(); } - public function provideUnion() + public static function provideUnion() { return [ // Note that a default (null) UNION is identical to a DISTINCT UNION @@ -899,9 +894,7 @@ public function provideUnion() ]; } - /** - * @dataProvider provideUnion - */ + #[DataProvider('provideUnion')] public function testUnion(SQLSelect $unionQuery, ?string $type, string|array $expected) { if (is_string($expected)) { @@ -954,7 +947,7 @@ public function testBaseTableAliases() ); } - public function provideWith() + public static function provideWith() { // Each of these examples shows it working with aliased implicit columns, and with explicit CTE columns. // Most of these examples are derived from https://dev.mysql.com/doc/refman/8.4/en/with.html @@ -1247,9 +1240,7 @@ public function provideWith() ]; } - /** - * @dataProvider provideWith - */ + #[DataProvider('provideWith')] public function testWith( string $name, SQLSelect $query, @@ -1328,7 +1319,7 @@ public function testMultipleWithDuplicateName() $select->addWith('cte', new SQLSelect()); } - public function subqueryProvider() + public static function subqueryProvider() { return [ 'no-explicit-alias-string' => ['( SELECT DISTINCT "SQLSelectTest_DO"."ClassName" FROM "SQLSelectTest_DO") AS "FINAL"'], @@ -1338,9 +1329,7 @@ public function subqueryProvider() ]; } - /** - * @dataProvider subqueryProvider - */ + #[DataProvider('subqueryProvider')] public function testSubqueries($subquery) { $query = new SQLSelect('*', $subquery); @@ -1353,7 +1342,7 @@ public function testSubqueries($subquery) ); } - public function addFromProvider() + public static function addFromProvider() { return [ 'string' => [ @@ -1391,9 +1380,7 @@ public function addFromProvider() ]; } - /** - * @dataProvider addFromProvider - */ + #[DataProvider('addFromProvider')] public function testAddFrom($input, $out, $message = ""): void { $query = new SQLSelect(); diff --git a/tests/php/ORM/Search/BasicSearchContextTest.php b/tests/php/ORM/Search/BasicSearchContextTest.php index 58c97aacd03..8887a5fa757 100644 --- a/tests/php/ORM/Search/BasicSearchContextTest.php +++ b/tests/php/ORM/Search/BasicSearchContextTest.php @@ -14,6 +14,7 @@ use SilverStripe\ORM\Filters\StartsWithFilter; use SilverStripe\ORM\Search\BasicSearchContext; use SilverStripe\View\ArrayData; +use PHPUnit\Framework\Attributes\DataProvider; class BasicSearchContextTest extends SapphireTest { @@ -96,7 +97,7 @@ public function testResultSetFilterReturnsExpectedCount() $this->assertEquals(1, $results->Count()); } - public function provideApplySearchFilters() + public static function provideApplySearchFilters() { $idFilter = new ExactMatchFilter('ID'); $idFilter->setModifiers(['nocase']); @@ -130,9 +131,7 @@ public function provideApplySearchFilters() ]; } - /** - * @dataProvider provideApplySearchFilters - */ + #[DataProvider('provideApplySearchFilters')] public function testApplySearchFilters(array $searchParams, ?array $filters, array $expected) { $context = new BasicSearchContext(ArrayData::class); @@ -146,7 +145,7 @@ public function testApplySearchFilters(array $searchParams, ?array $filters, arr $this->assertSame($expected, $reflectionApplySearchFilters->invoke($context, $searchParams)); } - public function provideGetGeneralSearchFilterTerm() + public static function provideGetGeneralSearchFilterTerm() { return [ 'defaults to case-insensitive partial match' => [ @@ -172,9 +171,7 @@ public function provideGetGeneralSearchFilterTerm() ]; } - /** - * @dataProvider provideGetGeneralSearchFilterTerm - */ + #[DataProvider('provideGetGeneralSearchFilterTerm')] public function testGetGeneralSearchFilterTerm(?string $filterType, ?SearchFilter $fieldFilter, string $expected) { $context = new BasicSearchContext(ArrayData::class); @@ -190,7 +187,7 @@ public function testGetGeneralSearchFilterTerm(?string $filterType, ?SearchFilte $this->assertSame($expected, $reflectionGetGeneralSearchFilterTerm->invoke($context, 'MyField')); } - public function provideGetQuery() + public static function provideGetQuery() { // Note that the search TERM is the same for both scenarios, // but because the search FIELD is different, we get different results. @@ -226,9 +223,7 @@ public function provideGetQuery() ]; } - /** - * @dataProvider provideGetQuery - */ + #[DataProvider('provideGetQuery')] public function testGetQuery(array $searchParams, array $expected) { $list = $this->getList(); diff --git a/tests/php/ORM/UniqueKey/ServiceTest.php b/tests/php/ORM/UniqueKey/ServiceTest.php index d0e78a969ae..c90991e81cb 100644 --- a/tests/php/ORM/UniqueKey/ServiceTest.php +++ b/tests/php/ORM/UniqueKey/ServiceTest.php @@ -5,6 +5,7 @@ use SilverStripe\Core\Injector\Injector; use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\DataObject; +use PHPUnit\Framework\Attributes\DataProvider; class ServiceTest extends SapphireTest { @@ -21,8 +22,8 @@ class ServiceTest extends SapphireTest * @param string $class * @param bool $extraKeys * @param string $expected - * @dataProvider uniqueKeysProvider */ + #[DataProvider('uniqueKeysProvider')] public function testUniqueKey(int $id, string $class, bool $extraKeys, string $expected): void { if ($extraKeys) { @@ -40,7 +41,7 @@ public function testUniqueKey(int $id, string $class, bool $extraKeys, string $e } } - public function uniqueKeysProvider(): array + public static function uniqueKeysProvider(): array { return [ [1, River::class, false, 'River-1-8d3310e232f75a01f5a0c9344655263d'], diff --git a/tests/php/Security/Confirmation/StorageTest.php b/tests/php/Security/Confirmation/StorageTest.php index d785b6d68dd..d599796970a 100644 --- a/tests/php/Security/Confirmation/StorageTest.php +++ b/tests/php/Security/Confirmation/StorageTest.php @@ -21,9 +21,9 @@ public function testNewStorage() { $session = $this->createMock(Session::class); $sessionCleaned = false; - $session->method('clear')->will($this->returnCallback(static function ($namespace) use (&$sessionCleaned) { + $session->method('clear')->willReturnCallback(static function ($namespace) use (&$sessionCleaned) { $sessionCleaned = $namespace; - })); + }); $storage = new Storage($session, 'test'); @@ -42,9 +42,9 @@ public function testCleanup() { $session = $this->createMock(Session::class); $sessionCleaned = false; - $session->method('clear')->will($this->returnCallback(static function ($namespace) use (&$sessionCleaned) { + $session->method('clear')->willReturnCallback(static function ($namespace) use (&$sessionCleaned) { $sessionCleaned = $namespace; - })); + }); $storage = new Storage($session, 'test', false); diff --git a/tests/php/Security/MemberAuthenticator/ChangePasswordHandlerTest.php b/tests/php/Security/MemberAuthenticator/ChangePasswordHandlerTest.php index f318d01f3d5..6662fa1befa 100644 --- a/tests/php/Security/MemberAuthenticator/ChangePasswordHandlerTest.php +++ b/tests/php/Security/MemberAuthenticator/ChangePasswordHandlerTest.php @@ -34,14 +34,16 @@ public function testExpiredOrInvalidTokenProvidesLostPasswordAndLoginLink() ]); $request->setSession(new Session([])); - /** @var ChangePasswordHandler $handler */ - $handler = $this->getMockBuilder(ChangePasswordHandler::class) - ->disableOriginalConstructor() - ->setMethods(null) - ->getMock(); + // not using a phpunit mock otherwise get the error + // Error: Typed property MockObject_ChangePasswordHandler_12f49d86::$__phpunit_state + // must not be accessed before initialization + $handler = new class() extends ChangePasswordHandler { + public function __construct() + { + } + }; $result = $handler->setRequest($request)->changepassword(); - $this->assertIsArray($result, 'An array is returned'); $this->assertStringContainsString('Security/lostpassword', $result['Content'], 'Lost password URL is included'); $this->assertStringContainsString('Security/login', $result['Content'], 'Login URL is included'); diff --git a/tests/php/Security/MemberTest.php b/tests/php/Security/MemberTest.php index cea9ab172ef..ebe5c03759e 100644 --- a/tests/php/Security/MemberTest.php +++ b/tests/php/Security/MemberTest.php @@ -35,6 +35,7 @@ use SilverStripe\Security\Tests\MemberTest\FieldsExtension; use SilverStripe\SessionManager\Models\LoginSession; use ReflectionMethod; +use PHPUnit\Framework\Attributes\DataProvider; class MemberTest extends FunctionalTest { @@ -1647,9 +1648,6 @@ public function testCurrentUser() $this->assertEquals($adminMember->ID, $userFromSession->ID); } - /** - * @covers \SilverStripe\Security\Member::actAs() - */ public function testActAsUserPermissions() { $this->assertNull(Security::getCurrentUser()); @@ -1686,9 +1684,6 @@ public function testActAsUserPermissions() $this->assertTrue($checkAdmin); } - /** - * @covers \SilverStripe\Security\Member::actAs() - */ public function testActAsUser() { $this->assertNull(Security::getCurrentUser()); @@ -1794,9 +1789,7 @@ public function testMapInCMSGroupsNoLeftAndMain() $this->assertEmpty($result, 'Without LeftAndMain, no groups are CMS groups.'); } - /** - * @dataProvider provideMapInCMSGroups - */ + #[DataProvider('provideMapInCMSGroups')] public function testMapInCMSGroups(array $groupFixtures, array $groupCodes, array $expectedUsers) { if (!empty($groupFixtures) && !empty($groupCodes)) { @@ -1837,7 +1830,7 @@ public function testMapInCMSGroups(array $groupFixtures, array $groupCodes, arra $this->assertEqualsCanonicalizing($expectedUsers, $result->keys()); } - public function provideMapInCMSGroups() + public static function provideMapInCMSGroups() { // Note: "ADMIN User" is not from the fixtures, that user is created by $this->logInWithPermission('ADMIN') return [ @@ -1860,7 +1853,7 @@ public function provideMapInCMSGroups() ], ], 'single group in IDs array' => [ - 'groups' => [ + 'groupFixtures' => [ 'staffgroup', ], 'groupCodes' => [], diff --git a/tests/php/Security/Member_GroupSetTest.php b/tests/php/Security/Member_GroupSetTest.php index a7992a1464a..64ab937c820 100644 --- a/tests/php/Security/Member_GroupSetTest.php +++ b/tests/php/Security/Member_GroupSetTest.php @@ -6,6 +6,7 @@ use SilverStripe\Security\Tests\GroupTest\TestMember; use SilverStripe\Core\Config\Config; use SilverStripe\ORM\DataList; +use PHPUnit\Framework\Attributes\DataProvider; class Member_GroupSetTest extends SapphireTest { @@ -15,9 +16,7 @@ class Member_GroupSetTest extends SapphireTest TestMember::class ]; - /** - * @dataProvider provideForForeignIDPlaceholders - */ + #[DataProvider('provideForForeignIDPlaceholders')] public function testForForeignIDPlaceholders(bool $config, bool $useInt, bool $expected): void { Config::modify()->set(DataList::class, 'use_placeholders_for_integer_ids', $config); @@ -34,10 +33,12 @@ public function testForForeignIDPlaceholders(bool $config, bool $useInt, bool $e $expectedIDs = $useInt ? array_unique(array_merge($groups1->column('ID'), $groups2->column('ID'))) : []; - $this->assertEqualsCanonicalizing($expectedIDs, $newGroupList->column('ID')); + sort($expectedIDs); + $actual = $newGroupList->sort('ID')->column('ID'); + $this->assertSame($expectedIDs, $actual); } - public function provideForForeignIDPlaceholders(): array + public static function provideForForeignIDPlaceholders(): array { return [ 'config false' => [ diff --git a/tests/php/Security/PasswordExpirationMiddlewareTest.php b/tests/php/Security/PasswordExpirationMiddlewareTest.php index ce3799e0b2a..6d49a495b7b 100644 --- a/tests/php/Security/PasswordExpirationMiddlewareTest.php +++ b/tests/php/Security/PasswordExpirationMiddlewareTest.php @@ -33,7 +33,7 @@ protected function setUp(): void private function getMemberMock($isPasswordExpired) : Member { $mock = $this->createMock(Member::class); - $mock->method('isPasswordExpired')->will($this->returnValue($isPasswordExpired)); + $mock->method('isPasswordExpired')->willReturn($isPasswordExpired); return $mock; } @@ -61,8 +61,6 @@ public function test200() * Check a member with an expired password is allowed to process the request in * deauthorised mode (Security::getCurrentUser() === null) if there are no * change password redirects registered - * - * @depends test200 */ public function testDeauthorised() { @@ -87,8 +85,6 @@ public function testDeauthorised() /** * Check a member with an expired password is redirected to a change password form * instead of processing its original request - * - * @depends test200 */ public function testRedirected() { @@ -98,7 +94,7 @@ public function testRedirected() $a = new PasswordExpirationMiddleware(); $request = $this->buildRequestMock('/'); - $request->method('getAcceptMimetypes')->will($this->returnValue(['*/*'])); + $request->method('getAcceptMimetypes')->willReturn(['*/*']); $session = $request->getSession(); $a->setRedirect($session, '/redirect-address-custom'); @@ -120,8 +116,6 @@ public function testRedirected() /** * Check we handle network locations correctly (the relative urls starting with //) - * - * @depends testRedirected */ public function testNetworkLocationRedirect() { @@ -131,7 +125,7 @@ public function testNetworkLocationRedirect() $a = new PasswordExpirationMiddleware(); $request = $this->buildRequestMock('/'); - $request->method('getAcceptMimetypes')->will($this->returnValue(['*/*'])); + $request->method('getAcceptMimetypes')->willReturn(['*/*']); $session = $request->getSession(); $a->setRedirect($session, '//localhost/custom-base/redirect-address-custom'); @@ -153,9 +147,6 @@ public function testNetworkLocationRedirect() /** * Check we can allow the current request handling even with an expired password - * - * @depends test200 - * @depends testDeauthorised */ public function testAllowRequest() { @@ -183,8 +174,6 @@ public function testAllowRequest() /** * Check a member with an expired password is redirected to a default change password form * if a custom not set - * - * @depends testRedirected */ public function testDefaultRedirect() { @@ -196,7 +185,7 @@ public function testDefaultRedirect() $a = new PasswordExpirationMiddleware(); $request = $this->buildRequestMock('/'); - $request->method('getAcceptMimetypes')->will($this->returnValue(['*/*'])); + $request->method('getAcceptMimetypes')->willReturn(['*/*']); $session = $request->getSession(); $executed = false; @@ -217,8 +206,6 @@ public function testDefaultRedirect() /** * Check a member with an expired password is redirected to a default change password form * if a custom not set - * - * @depends testDefaultRedirect */ public function testCustomRedirect() { @@ -230,7 +217,7 @@ public function testCustomRedirect() $a = new PasswordExpirationMiddleware(); $request = $this->buildRequestMock('/'); - $request->method('getAcceptMimetypes')->will($this->returnValue(['*/*'])); + $request->method('getAcceptMimetypes')->willReturn(['*/*']); $executed = false; $activeMember = null; @@ -249,8 +236,6 @@ public function testCustomRedirect() /** * Check a custom redirect URL overrides the default one - * - * @depends testCustomRedirect */ public function testCustomOverDefaultRedirect() { @@ -262,7 +247,7 @@ public function testCustomOverDefaultRedirect() $a = new PasswordExpirationMiddleware(); $request = $this->buildRequestMock('/'); - $request->method('getAcceptMimetypes')->will($this->returnValue(['*/*'])); + $request->method('getAcceptMimetypes')->willReturn(['*/*']); $session = $request->getSession(); $a->setRedirect($session, '/redirect-address-custom'); @@ -283,8 +268,6 @@ public function testCustomOverDefaultRedirect() /** * Test we can allow URLs to be visited without redirections through config - * - * @depends testRedirected */ public function testAllowedUrlStartswithNegative() { @@ -298,7 +281,7 @@ public function testAllowedUrlStartswithNegative() $a = new PasswordExpirationMiddleware(); $request = $this->buildRequestMock('/not-allowed'); - $request->method('getAcceptMimetypes')->will($this->returnValue(['*/*'])); + $request->method('getAcceptMimetypes')->willReturn(['*/*']); $session = $request->getSession(); $a->setRedirect($session, '/redirect-address-custom'); @@ -320,8 +303,6 @@ public function testAllowedUrlStartswithNegative() /** * Test we can allow URLs to be visited without redirections through config - * - * @depends testRedirected */ public function testAllowedUrlStartswithPositivePattern() { @@ -335,7 +316,7 @@ public function testAllowedUrlStartswithPositivePattern() $a = new PasswordExpirationMiddleware(); $request = $this->buildRequestMock('/allowed-address-configured/subsection1/subsection2/'); - $request->method('getAcceptMimetypes')->will($this->returnValue(['*/*'])); + $request->method('getAcceptMimetypes')->willReturn(['*/*']); $session = $request->getSession(); $a->setRedirect($session, '/redirect-address-custom'); @@ -364,7 +345,7 @@ public function testAllowedUrlStartswithPositiveTrailingSlash() $a = new PasswordExpirationMiddleware(); $request = $this->buildRequestMock('/allowed-address-configured?foo=bar'); - $request->method('getAcceptMimetypes')->will($this->returnValue(['*/*'])); + $request->method('getAcceptMimetypes')->willReturn(['*/*']); $session = $request->getSession(); $a->setRedirect($session, '/redirect-address-custom'); @@ -393,7 +374,7 @@ public function testAllowedUrlStartswithPositiveRelativeUrl() $a = new PasswordExpirationMiddleware(); $request = $this->buildRequestMock('/allowed-address-configured?foo=bar'); - $request->method('getAcceptMimetypes')->will($this->returnValue(['*/*'])); + $request->method('getAcceptMimetypes')->willReturn(['*/*']); $session = $request->getSession(); $a->setRedirect($session, 'redirect-address-custom'); @@ -412,8 +393,6 @@ public function testAllowedUrlStartswithPositiveRelativeUrl() /** * Test we can allow URLs to be visited without redirections through config - * - * @depends testRedirected */ public function testAllowedUrlStartswithPositiveExactUrl() { @@ -427,7 +406,7 @@ public function testAllowedUrlStartswithPositiveExactUrl() $a = new PasswordExpirationMiddleware(); $request = $this->buildRequestMock('/allowed-address-configured/'); - $request->method('getAcceptMimetypes')->will($this->returnValue(['*/*'])); + $request->method('getAcceptMimetypes')->willReturn(['*/*']); $session = $request->getSession(); $a->setRedirect($session, '/redirect-address-custom'); diff --git a/tests/php/Security/RememberLoginHashTest.php b/tests/php/Security/RememberLoginHashTest.php index ced2991af5d..cf98add99a6 100644 --- a/tests/php/Security/RememberLoginHashTest.php +++ b/tests/php/Security/RememberLoginHashTest.php @@ -7,6 +7,7 @@ use SilverStripe\Security\RememberLoginHash; use SilverStripe\SessionManager\Models\LoginSession; use SilverStripe\Dev\Deprecation; +use PHPUnit\Framework\Attributes\DataProvider; class RememberLoginHashTest extends SapphireTest { @@ -32,7 +33,7 @@ protected function setUp(): void ]; } - public function clearScenarios() + public static function clearScenarios() { return [ 'logout across devices' => [true, 'current', ['secondary'], ['current', 'other']], @@ -47,8 +48,8 @@ public function clearScenarios() * @param mixed $deviceId * @param array $expected * @param array $unexpected - * @dataProvider clearScenarios */ + #[DataProvider('clearScenarios')] public function testClear(bool $logoutAcrossDevices, $deviceId, array $expected, array $unexpected) { // If session-manager module is installed then logout_across_devices is modified so skip @@ -98,9 +99,9 @@ public function testGetSetLogoutAcrossDevices() } /** - * @dataProvider provideRenew * @param bool $replaceToken */ + #[DataProvider('provideRenew')] public function testRenew($replaceToken) { // If session-manager module is installed it expects an active request during renewal @@ -132,7 +133,7 @@ public function testRenew($replaceToken) } } - public function provideRenew(): array + public static function provideRenew(): array { return [ [true], diff --git a/tests/php/View/AttributesHTMLTest.php b/tests/php/View/AttributesHTMLTest.php index 36f48b89a69..881bf0eef51 100644 --- a/tests/php/View/AttributesHTMLTest.php +++ b/tests/php/View/AttributesHTMLTest.php @@ -4,11 +4,11 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\View\Tests\AttributesHTMLTest\DummyAttributesHTML; +use PHPUnit\Framework\Attributes\DataProvider; class AttributesHTMLTest extends SapphireTest { - - public function provideGetAttribute(): array + public static function provideGetAttribute(): array { return [ 'empty string' => ['test', '', 'Empty string is not converted to a different falsy value'], @@ -23,7 +23,7 @@ public function provideGetAttribute(): array ]; } - /** @dataProvider provideGetAttribute */ + #[DataProvider('provideGetAttribute')] public function testGetAttribute($name, $value, $message): void { $dummy = new DummyAttributesHTML(); diff --git a/tests/php/View/Parsers/HTMLValueTest.php b/tests/php/View/Parsers/HTMLValueTest.php index 52563498ace..c15eb1a4a34 100644 --- a/tests/php/View/Parsers/HTMLValueTest.php +++ b/tests/php/View/Parsers/HTMLValueTest.php @@ -7,6 +7,7 @@ use SilverStripe\ORM\FieldType\DBHTMLText; use SilverStripe\View\Parsers\ShortcodeParser; use SilverStripe\Core\Convert; +use PHPUnit\Framework\Attributes\DataProvider; class HTMLValueTest extends SapphireTest { @@ -161,7 +162,7 @@ public function testValidHTMLInNoscriptTags() } } - public function provideOnlyStripIntendedTags(): array + public static function provideOnlyStripIntendedTags(): array { return [ [ @@ -179,9 +180,7 @@ public function provideOnlyStripIntendedTags(): array ]; } - /** - * @dataProvider provideOnlyStripIntendedTags - */ + #[DataProvider('provideOnlyStripIntendedTags')] public function testOnlyStripIntendedTags(string $input, string $expected): void { $value = new HTMLValue(); diff --git a/tests/php/View/Parsers/HtmlDiffTest.php b/tests/php/View/Parsers/HtmlDiffTest.php index d89723cdd2f..e3fb0525fc3 100644 --- a/tests/php/View/Parsers/HtmlDiffTest.php +++ b/tests/php/View/Parsers/HtmlDiffTest.php @@ -5,6 +5,8 @@ use SebastianBergmann\Diff\Differ; use SilverStripe\Dev\SapphireTest; use SilverStripe\View\Parsers\HtmlDiff; +use PHPUnit\Framework\Attributes\DataProvider; +use SebastianBergmann\Diff\Output\DiffOnlyOutputBuilder; class HtmlDiffTest extends SapphireTest { @@ -49,7 +51,7 @@ public function testEndOfLineDoesntNeedHandling() // Ensure that this test is valid and that those changes would include an end-of-line warning // in a direct call to the underlying differ - $differ = new Differ(); + $differ = new Differ(new DiffOnlyOutputBuilder()); $expected = [ [ '#Warning: Strings contain different line endings!' . "\n", @@ -67,7 +69,7 @@ public function testEndOfLineDoesntNeedHandling() $this->assertSame($expected, $differ->diffToArray($from, $to)); } - public function provideCompareHtml(): array + public static function provideCompareHtml(): array { return [ [ @@ -148,9 +150,7 @@ public function provideCompareHtml(): array ]; } - /** - * @dataProvider provideCompareHtml - */ + #[DataProvider('provideCompareHtml')] public function testCompareHTML(string|array $from, string|array $to, bool $escape, string $expected) { $diff = HtmlDiff::compareHtml($from, $to, $escape); diff --git a/tests/php/View/Parsers/ShortcodeParserTest.php b/tests/php/View/Parsers/ShortcodeParserTest.php index 2853232d202..fbee4660930 100644 --- a/tests/php/View/Parsers/ShortcodeParserTest.php +++ b/tests/php/View/Parsers/ShortcodeParserTest.php @@ -4,6 +4,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\View\Parsers\ShortcodeParser; +use PHPUnit\Framework\Attributes\DataProvider; class ShortcodeParserTest extends SapphireTest { @@ -79,7 +80,7 @@ public function testNotRegisteredShortcode() ); } - public function simpleTagDataProvider() + public static function simpleTagDataProvider() { return [ ['[test_shortcode]'], @@ -92,9 +93,7 @@ public function simpleTagDataProvider() ]; } - /** - * @dataProvider simpleTagDataProvider - */ + #[DataProvider('simpleTagDataProvider')] public function testSimpleTag($test) { $this->parser->parse($test); @@ -103,7 +102,7 @@ public function testSimpleTag($test) $this->assertEquals('test_shortcode', $this->tagName, $test); } - public function oneArgumentDataProvider() + public static function oneArgumentDataProvider() { return [ ['[test_shortcode foo="bar"]'], @@ -117,9 +116,7 @@ public function oneArgumentDataProvider() ]; } - /** - * @dataProvider oneArgumentDataProvider - */ + #[DataProvider('oneArgumentDataProvider')] public function testOneArgument($test) { $this->parser->parse($test); @@ -138,7 +135,7 @@ public function testMultipleArguments() $this->assertEquals('test_shortcode', $this->tagName); } - public function emptyArgumentsDataProvider() + public static function emptyArgumentsDataProvider() { return [ ['[test_shortcode foo=""]'], @@ -147,9 +144,7 @@ public function emptyArgumentsDataProvider() ]; } - /** - * @dataProvider emptyArgumentsDataProvider - */ + #[DataProvider('emptyArgumentsDataProvider')] public function testEmptyArguments($test) { $this->parser->parse($test); @@ -359,7 +354,7 @@ public function testShortcodeWithAnchorAndQuerystring() public function testNoParseAttemptIfNoCode() { - $stub = $this->getMockBuilder(ShortcodeParser::class)->setMethods(['replaceElementTagsWithMarkers']) + $stub = $this->getMockBuilder(ShortcodeParser::class)->onlyMethods(['replaceElementTagsWithMarkers']) ->getMock(); $stub->register( 'test', @@ -369,7 +364,7 @@ function () { ); $stub->expects($this->never()) - ->method('replaceElementTagsWithMarkers')->will($this->returnValue(['', ''])); + ->method('replaceElementTagsWithMarkers')->willReturn(['', '']); $stub->parse('

test

'); } diff --git a/tests/php/View/SSViewerTest.php b/tests/php/View/SSViewerTest.php index f1eb6d76bed..45af82fbd72 100644 --- a/tests/php/View/SSViewerTest.php +++ b/tests/php/View/SSViewerTest.php @@ -33,6 +33,8 @@ use SilverStripe\View\Tests\SSViewerTest\SSViewerTestModelController; use SilverStripe\View\Tests\SSViewerTest\TestViewableData; use SilverStripe\View\ViewableData; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\DoesNotPerformAssertions; class SSViewerTest extends SapphireTest { @@ -208,7 +210,7 @@ public function testRequirements() /** @var Requirements_Backend|MockObject $requirements */ $requirements = $this ->getMockBuilder(Requirements_Backend::class) - ->setMethods(["javascript", "css"]) + ->onlyMethods(["javascript", "css"]) ->getMock(); $jsFile = FRAMEWORK_DIR . '/tests/forms/a.js'; $cssFile = FRAMEWORK_DIR . '/tests/forms/a.js'; @@ -567,7 +569,7 @@ public function testCurrentScopeLoopWith() $this->assertEquals("SubKid1SubKid2Number6", $result, "Loop in current scope works"); } - public function provideArgumentTypes() + public static function provideArgumentTypes() { return [ [ @@ -593,9 +595,7 @@ public function provideArgumentTypes() ]; } - /** - * @dataProvider provideArgumentTypes - */ + #[DataProvider('provideArgumentTypes')] public function testArgumentTypes(string $expected, string $template) { $this->assertEquals($expected, $this->render($template, new TestViewableData())); @@ -706,7 +706,7 @@ public function testLoopWhitespace() ); } - public function typePreservationDataProvider() + public static function typePreservationDataProvider() { return [ // Null @@ -763,9 +763,7 @@ public function typePreservationDataProvider() ]; } - /** - * @dataProvider typePreservationDataProvider - */ + #[DataProvider('typePreservationDataProvider')] public function testTypesArePreserved($expected, $templateArg) { $data = new ArrayData([ @@ -775,9 +773,7 @@ public function testTypesArePreserved($expected, $templateArg) $this->assertEquals($expected, $this->render("\$Test.Type({$templateArg})", $data)); } - /** - * @dataProvider typePreservationDataProvider - */ + #[DataProvider('typePreservationDataProvider')] public function testTypesArePreservedAsIncludeArguments($expected, $templateArg) { $data = new ArrayData([ @@ -1034,7 +1030,7 @@ public function testIfBlocks() ); } - public function provideIfBlockWithIterable(): array + public static function provideIfBlockWithIterable(): array { $scenarios = [ 'empty array' => [ @@ -1057,9 +1053,7 @@ public function provideIfBlockWithIterable(): array return $scenarios; } - /** - * @dataProvider provideIfBlockWithIterable - */ + #[DataProvider('provideIfBlockWithIterable')] public function testIfBlockWithIterable(iterable $iterable, bool $inScope): void { $expected = count($iterable) ? 'has value' : 'no value'; @@ -1387,7 +1381,7 @@ public function testCastingHelpers() ); } - public function provideLoop(): array + public static function provideLoop(): array { return [ 'nested array and iterator' => [ @@ -1422,16 +1416,14 @@ public function provideLoop(): array ]; } - /** - * @dataProvider provideLoop - */ + #[DataProvider('provideLoop')] public function testLoop(iterable $iterable, string $template, string $expected): void { $data = new ArrayData(['Iterable' => $iterable]); $this->assertEqualIgnoringWhitespace($expected, $this->render($template, $data)); } - public function provideCountIterable(): array + public static function provideCountIterable(): array { $scenarios = [ 'empty array' => [ @@ -1454,9 +1446,7 @@ public function provideCountIterable(): array return $scenarios; } - /** - * @dataProvider provideCountIterable - */ + #[DataProvider('provideCountIterable')] public function testCountIterable(iterable $iterable, bool $inScope): void { $expected = count($iterable); @@ -1878,9 +1868,6 @@ function () { ); } - /** - * @covers \SilverStripe\View\SSViewer::get_templates_by_class() - */ public function testGetTemplatesByClass() { $this->useTestTheme( @@ -2369,10 +2356,15 @@ public function testPrimitivesConvertedToDBFields() ); } + #[DoesNotPerformAssertions] public function testMe(): void { - $mockArrayData = $this->getMockBuilder(ArrayData::class)->addMethods(['forTemplate'])->getMock(); - $mockArrayData->expects($this->once())->method('forTemplate')->willReturn(''); - $this->render('$Me', $mockArrayData); + $myArrayData = new class extends ArrayData { + public function forTemplate() + { + return ''; + } + }; + $this->render('$Me', $myArrayData); } } diff --git a/tests/php/View/ViewableDataTest.php b/tests/php/View/ViewableDataTest.php index 9f24042cd6b..69b93d3b77d 100644 --- a/tests/php/View/ViewableDataTest.php +++ b/tests/php/View/ViewableDataTest.php @@ -12,6 +12,7 @@ use SilverStripe\View\Tests\ViewableDataTest\ViewableDataTestExtension; use SilverStripe\View\Tests\ViewableDataTest\ViewableDataTestObject; use SilverStripe\View\ViewableData; +use PHPUnit\Framework\Attributes\DataProvider; /** * See {@link SSViewerTest->testCastingHelpers()} for more tests related to casting and ViewableData behaviour, @@ -284,7 +285,7 @@ public function testDynamicData() $this->assertSame($obj, $viewableData->abc); } - public function provideWrapArrayInObj(): array + public static function provideWrapArrayInObj(): array { return [ 'empty array' => [ @@ -301,9 +302,7 @@ public function provideWrapArrayInObj(): array ]; } - /** - * @dataProvider provideWrapArrayInObj - */ + #[DataProvider('provideWrapArrayInObj')] public function testWrapArrayInObj(array $arr, string $expectedClass): void { $viewableData = new ViewableData(); diff --git a/tests/php/i18n/YamlReaderTest.php b/tests/php/i18n/YamlReaderTest.php index 68f60ca28af..b7d55feb4ae 100644 --- a/tests/php/i18n/YamlReaderTest.php +++ b/tests/php/i18n/YamlReaderTest.php @@ -8,9 +8,6 @@ class YamlReaderTest extends SapphireTest { - /** - * - */ public function testRead() { $reader = new YamlReader(); diff --git a/tests/php/i18n/i18nTest.php b/tests/php/i18n/i18nTest.php index 79882c9407f..8fecae91fd2 100644 --- a/tests/php/i18n/i18nTest.php +++ b/tests/php/i18n/i18nTest.php @@ -12,6 +12,7 @@ use SilverStripe\i18n\Messages\Symfony\SymfonyMessageProvider; use SilverStripe\View\ArrayData; use SilverStripe\View\SSViewer; +use PHPUnit\Framework\Attributes\DataProvider; class i18nTest extends SapphireTest { @@ -426,7 +427,7 @@ public function testTranslate() ); } - public function pluralisationDataProvider() + public static function pluralisationDataProvider() { return [ // English - 2 plural forms @@ -451,11 +452,11 @@ public function pluralisationDataProvider() } /** - * @dataProvider pluralisationDataProvider() * @param string $locale * @param int $count * @param string $expected */ + #[DataProvider('pluralisationDataProvider')] public function testPluralisation($locale, $count, $expected) { i18n::set_locale($locale); diff --git a/tests/php/i18n/i18nTextCollectorTest.php b/tests/php/i18n/i18nTextCollectorTest.php index f1be3b99382..6fe81c6e44e 100644 --- a/tests/php/i18n/i18nTextCollectorTest.php +++ b/tests/php/i18n/i18nTextCollectorTest.php @@ -6,10 +6,12 @@ use SilverStripe\Core\Manifest\ModuleLoader; use SilverStripe\Core\Manifest\ModuleManifest; use SilverStripe\Core\Path; +use SilverStripe\Dev\Exceptions\ExpectedNoticeException; use SilverStripe\Dev\SapphireTest; use SilverStripe\i18n\i18n; use SilverStripe\i18n\Messages\YamlWriter; use SilverStripe\i18n\Tests\i18nTextCollectorTest\Collector; +use SilverStripe\i18n\Tests\i18nTextCollectorTest\i18nTextCollectorTestException; use SilverStripe\i18n\TextCollection\i18nTextCollector; class i18nTextCollectorTest extends SapphireTest @@ -74,6 +76,8 @@ public function testConcatenationInEntityValues() public function testCollectFromNewTemplateSyntaxUsingParserSubclass() { + $this->enableErrorHandler(); + $c = i18nTextCollector::create(); $c->setWarnOnEmptyDefault(false); $mymodule = ModuleLoader::inst()->getManifest()->getModule('i18ntestmodule'); @@ -115,8 +119,8 @@ public function testCollectFromNewTemplateSyntaxUsingParserSubclass() // Test warning is raised on empty default $c->setWarnOnEmptyDefault(true); - $this->expectNotice(); - $this->expectNoticeMessage('Missing localisation default for key i18nTestModule.INJECTIONS_3'); + $this->expectException(ExpectedNoticeException::class); + $this->expectExceptionMessage('Missing localisation default for key i18nTestModule.INJECTIONS_3'); $c->collectFromTemplate($html, null, $mymodule); } @@ -153,6 +157,7 @@ public function testCollectFromTemplateSimple() public function testCollectFromTemplateAdvanced() { + $this->enableErrorHandler(); $c = i18nTextCollector::create(); $c->setWarnOnEmptyDefault(false); $mymodule = ModuleLoader::inst()->getManifest()->getModule('i18ntestmodule'); @@ -190,8 +195,8 @@ public function testCollectFromTemplateAdvanced() // Test warning is raised on empty default $c->setWarnOnEmptyDefault(true); - $this->expectNotice(); - $this->expectNoticeMessage('Missing localisation default for key Test.PRIOANDCOMMENT'); + $this->expectException(ExpectedNoticeException::class); + $this->expectExceptionMessage('Missing localisation default for key Test.PRIOANDCOMMENT'); $c->collectFromTemplate($html, 'Test', $mymodule); } @@ -479,6 +484,7 @@ public function testNewlinesInEntityValues() */ public function testCollectFromCodeNewSignature() { + $this->enableErrorHandler(); $c = i18nTextCollector::create(); $c->setWarnOnEmptyDefault(false); // Disable warnings for tests $mymodule = ModuleLoader::inst()->getManifest()->getModule('i18ntestmodule'); @@ -523,8 +529,8 @@ public function testCollectFromCodeNewSignature() $this->assertEquals($expectedArray, $collectedTranslatables); // Test warning is raised on empty default - $this->expectNotice(); - $this->expectNoticeMessage('Missing localisation default for key i18nTestModule.INJECTIONS4'); + $this->expectException(ExpectedNoticeException::class); + $this->expectExceptionMessage('Missing localisation default for key i18nTestModule.INJECTIONS4'); $php = <<"Cat", "greeting"=>"meow", "goodbye"=>"meow"]);