From cd076542f4ec903048011d0e1c049f3a70d91307 Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Wed, 27 Oct 2021 15:39:47 +1300 Subject: [PATCH] API Upgrade SapphireTest to work with phpunit 9 (#10028) --- .travis.yml | 21 +- composer.json | 9 +- .../06_Testing/00_Unit_Testing.md | 18 +- .../How_Tos/00_Write_a_SapphireTest.md | 8 +- phpunit.xml.dist | 22 +- src/Dev/Constraint/SSListContains.php | 163 +- src/Dev/Constraint/SSListContainsOnly.php | 19 +- .../SSListContainsOnlyMatchingItems.php | 106 +- src/Dev/Constraint/ViewableDataContains.php | 114 +- src/Dev/FunctionalTest.php | 463 ++++++ src/Dev/SapphireTest.php | 1356 ++++++++++++++++- tests/behat/src/CmsFormsContext.php | 68 +- tests/behat/src/CmsUiContext.php | 71 +- tests/behat/src/ConfigContext.php | 9 +- tests/php/Control/ControllerTest.php | 16 +- tests/php/Control/CookieTest.php | 2 +- tests/php/Control/DirectorTest.php | 6 +- tests/php/Control/Email/EmailTest.php | 38 +- tests/php/Control/Email/SwiftPluginTest.php | 2 +- .../HTTPCacheControlIntegrationTest.php | 62 +- tests/php/Control/HTTPRequestTest.php | 3 +- tests/php/Control/HTTPTest.php | 42 +- tests/php/Control/IPUtilsTest.php | 10 +- .../Middleware/CanonicalURLMiddlewareTest.php | 4 +- .../HTTPCacheControlMiddlewareTest.php | 48 +- .../Middleware/RateLimitMiddlewareTest.php | 2 +- tests/php/Control/RSS/RSSFeedTest.php | 46 +- tests/php/Control/RequestHandlingTest.php | 2 +- tests/php/Control/SessionTest.php | 8 +- .../SimpleResourceURLGeneratorTest.php | 2 +- tests/php/Core/Cache/CacheTest.php | 2 +- tests/php/Core/Cache/RateLimiterTest.php | 2 +- tests/php/Core/ClassInfoTest.php | 7 +- tests/php/Core/ConvertTest.php | 6 +- tests/php/Core/CoreTest.php | 4 +- tests/php/Core/Injector/InjectorTest.php | 21 +- tests/php/Core/Manifest/ClassLoaderTest.php | 2 +- .../ClassManifestErrorHandlerTest.php | 6 +- tests/php/Core/Manifest/ClassManifestTest.php | 2 +- .../php/Core/Manifest/ConfigManifestTest.php | 6 +- .../Core/Manifest/ManifestFileFinderTest.php | 2 +- .../php/Core/Manifest/ModuleManifestTest.php | 2 +- .../php/Core/Manifest/ModuleResourceTest.php | 2 +- .../Manifest/NamespacedClassManifestTest.php | 17 +- .../php/Core/Manifest/PrioritySorterTest.php | 2 +- .../Core/Manifest/ThemeResourceLoaderTest.php | 4 +- .../php/Core/Manifest/VersionProviderTest.php | 46 +- .../module/classes/ClassI.php | 4 +- tests/php/Core/MemoryLimitTest.php | 23 +- tests/php/Core/ObjectTest.php | 2 +- tests/php/Core/PathTest.php | 2 +- tests/php/Core/PhpSyntaxTest.php | 2 +- tests/php/Dev/BulkLoaderResultTest.php | 2 +- tests/php/Dev/CLIDebugViewTest.php | 2 +- tests/php/Dev/CSVParserTest.php | 2 +- tests/php/Dev/CsvBulkLoaderTest.php | 2 +- tests/php/Dev/DebugViewTest.php | 2 +- tests/php/Dev/DeprecationTest.php | 35 +- tests/php/Dev/DevAdminControllerTest.php | 6 +- tests/php/Dev/FixtureBlueprintTest.php | 18 +- tests/php/Dev/SSListExporterTest.php | 2 +- tests/php/Dev/SapphireTestTest.php | 13 +- tests/php/Dev/YamlFixtureTest.php | 4 +- .../Forms/CheckboxSetFieldMultiEnumTest.php | 4 +- tests/php/Forms/CheckboxSetFieldTest.php | 14 +- tests/php/Forms/CompositeFieldTest.php | 14 +- .../php/Forms/ConfirmedPasswordFieldTest.php | 22 +- tests/php/Forms/CurrencyFieldDisabledTest.php | 12 +- tests/php/Forms/CurrencyFieldReadonlyTest.php | 18 +- tests/php/Forms/CurrencyFieldTest.php | 2 +- tests/php/Forms/DatalessFieldTest.php | 4 +- tests/php/Forms/DateFieldDisabledTest.php | 6 +- tests/php/Forms/DateFieldTest.php | 21 +- tests/php/Forms/DatetimeFieldTest.php | 12 +- tests/php/Forms/DefaultFormFactoryTest.php | 6 +- tests/php/Forms/EmailFieldTest.php | 6 +- tests/php/Forms/FormActionTest.php | 4 +- tests/php/Forms/FormFactoryTest.php | 2 +- tests/php/Forms/FormFieldTest.php | 50 +- tests/php/Forms/FormSchemaTest.php | 14 +- tests/php/Forms/FormTest.php | 50 +- .../GridField/GridFieldActionMenuTest.php | 2 +- .../GridField/GridFieldDataColumnsTest.php | 4 +- .../GridField/GridFieldDeleteActionTest.php | 2 +- .../GridField/GridFieldEditButtonTest.php | 10 +- .../GridField/GridFieldExportButtonTest.php | 2 +- .../GridField/GridFieldFilterHeaderTest.php | 8 +- .../GridField/GridFieldLazyLoaderTest.php | 26 +- .../GridField/GridFieldPaginatorTest.php | 2 +- .../GridField/GridFieldPrintButtonTest.php | 2 +- .../GridField/GridFieldSortableHeaderTest.php | 30 +- tests/php/Forms/GridField/GridFieldTest.php | 35 +- tests/php/Forms/GroupedDropdownFieldTest.php | 10 +- .../Forms/HTMLEditor/HTMLEditorConfigTest.php | 6 +- .../Forms/HTMLEditor/HTMLEditorFieldTest.php | 8 +- .../TinyMCECombinedGeneratorTest.php | 38 +- .../Forms/HTMLEditor/TinyMCEConfigTest.php | 2 +- tests/php/Forms/LookupFieldTest.php | 32 +- tests/php/Forms/NumericFieldTest.php | 6 +- tests/php/Forms/OptionsetFieldTest.php | 10 +- .../PrintableTransformationTabSetTest.php | 6 +- tests/php/Forms/SelectionGroupTest.php | 4 +- tests/php/Forms/TextareaFieldTest.php | 8 +- tests/php/Forms/TimeFieldReadonlyTest.php | 10 +- tests/php/Forms/TimeFieldTest.php | 21 +- tests/php/Forms/TipTest.php | 10 +- tests/php/Forms/TreeDropdownFieldTest.php | 4 +- tests/php/Forms/TreeMultiselectFieldTest.php | 19 +- .../DebugViewFriendlyErrorFormatterTest.php | 10 +- .../Logging/DetailedErrorFormatterTest.php | 24 +- tests/php/Logging/HTTPOutputHandlerTest.php | 2 +- tests/php/Logging/MonologErrorHandlerTest.php | 7 +- tests/php/ORM/ArrayListTest.php | 14 +- tests/php/ORM/DBDateTest.php | 20 +- tests/php/ORM/DBDatetimeTest.php | 8 +- tests/php/ORM/DBHTMLTextTest.php | 4 +- tests/php/ORM/DBTextTest.php | 4 +- tests/php/ORM/DBTimeTest.php | 6 +- tests/php/ORM/DataListTest.php | 42 +- .../ORM/DataObjectSchemaGenerationTest.php | 2 +- tests/php/ORM/DataObjectTest.php | 42 +- tests/php/ORM/DataObjectTest.yml | 2 +- tests/php/ORM/DataQueryTest.php | 21 +- tests/php/ORM/DatabaseTest.php | 50 +- tests/php/ORM/DecimalTest.php | 2 +- tests/php/ORM/HierarchyCachingTest.php | 4 +- tests/php/ORM/HierarchyTest.php | 2 +- tests/php/ORM/ListDecoratorTest.php | 15 +- tests/php/ORM/ManyManyListTest.php | 2 +- tests/php/ORM/ManyManyThroughListTest.php | 8 +- tests/php/ORM/MarkedSetTest.php | 2 +- tests/php/ORM/PaginatedListTest.php | 20 +- tests/php/ORM/SQLSelectTest.php | 55 +- .../php/ORM/Search/FulltextSearchableTest.php | 4 +- tests/php/ORM/TransactionTest.php | 8 +- tests/php/ORM/ValidationExceptionTest.php | 111 +- tests/php/Security/BasicAuthTest.php | 2 +- tests/php/Security/GroupTest.php | 4 +- .../InheritedPermissionsFlusherTest.php | 2 +- .../php/Security/InheritedPermissionsTest.php | 4 +- .../ChangePasswordHandlerTest.php | 8 +- .../php/Security/MemberAuthenticatorTest.php | 4 +- .../php/Security/MemberCsvBulkLoaderTest.php | 2 +- tests/php/Security/MemberTest.php | 28 +- tests/php/Security/PasswordEncryptorTest.php | 9 +- .../PasswordExpirationMiddlewareTest.php | 2 +- tests/php/Security/PasswordValidatorTest.php | 2 +- .../PermissionCheckboxSetFieldTest.php | 4 +- tests/php/Security/PermissionTest.php | 6 +- tests/php/Security/RememberLoginHashTest.php | 6 +- .../php/Security/SecurityDefaultAdminTest.php | 4 +- tests/php/Security/SecurityTest.php | 52 +- .../VersionedMemberAuthenticatorTest.php | 4 +- tests/php/View/ArrayDataTest.php | 8 - tests/php/View/ContentNegotiatorTest.php | 20 +- tests/php/View/HTMLTest.php | 2 +- tests/php/View/Parsers/DiffTest.php | 4 +- .../php/View/Parsers/ShortcodeParserTest.php | 14 +- tests/php/View/RequirementsTest.php | 166 +- tests/php/View/SSViewerCacheBlockTest.php | 13 +- tests/php/View/SSViewerTest.php | 52 +- tests/php/View/ViewableDataTest.php | 2 +- tests/php/i18n/YamlReaderTest.php | 2 +- tests/php/i18n/i18nTest.php | 42 +- tests/php/i18n/i18nTextCollectorTest.php | 33 +- 165 files changed, 3300 insertions(+), 1264 deletions(-) diff --git a/.travis.yml b/.travis.yml index ecc69a116..529543272 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ env: jobs: fast_finish: true include: - - php: 7.1 + - php: 7.3 env: - DB=MYSQL - REQUIRE_INSTALLER="$REQUIRE_RECIPE" @@ -20,21 +20,7 @@ jobs: - PHPUNIT_TEST=1 - PHPUNIT_SUITE="framework" - COMPOSER_INSTALL_ARG="--prefer-lowest" - - php: 7.2 - env: - - DB=PGSQL - - PDO=1 - - REQUIRE_INSTALLER="$REQUIRE_RECIPE" - - PHPUNIT_TEST=1 - - PHPUNIT_TEST="framework" - - php: 7.3 - env: - - DB=MYSQL - - PDO=1 - - REQUIRE_INSTALLER="$REQUIRE_RECIPE" - - PHPUNIT_TEST=1 - - PHPUNIT_SUITE="framework" - - php: 7.3 + - php: 7.4 env: - DB=MYSQL - REQUIRE_INSTALLER="$REQUIRE_RECIPE" @@ -46,10 +32,9 @@ jobs: - REQUIRE_INSTALLER="$REQUIRE_RECIPE" - PHPUNIT_TEST=1 - PHPUNIT_SUITE="framework" - - php: nightly + - php: 8.0 env: - DB=MYSQL - REQUIRE_INSTALLER="$REQUIRE_RECIPE" - PHPUNIT_TEST=1 - PHPUNIT_SUITE="framework" - - COMPOSER_INSTALL_ARG="--ignore-platform-reqs" diff --git a/composer.json b/composer.json index 9ac73f3bd..d803aac07 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,7 @@ "symfony/config": "^3.2 || ^4", "symfony/translation": "^2.8 || ^3 || ^4", "symfony/yaml": "^3.2 || ^4", - "php": "^7.1 || ^8", + "php": "^7.3 || ^8", "ext-ctype": "*", "ext-dom": "*", "ext-hash": "*", @@ -52,11 +52,14 @@ "ext-xml": "*" }, "require-dev": { - "sminnee/phpunit": "^5.7.29", - "sminnee/phpunit-mock-objects": "^3.4.9", + "phpunit/phpunit": "^9.5", + "dms/phpunit-arraysubset-asserts": "^0.3.0", "silverstripe/versioned": "^1", "squizlabs/php_codesniffer": "^3.5" }, + "conflict": { + "phpunit/phpunit": "^6 || ^7 || ^8" + }, "provide": { "psr/container-implementation": "1.0.0" }, diff --git a/docs/en/02_Developer_Guides/06_Testing/00_Unit_Testing.md b/docs/en/02_Developer_Guides/06_Testing/00_Unit_Testing.md index c1db2b6c8..68d8de045 100644 --- a/docs/en/02_Developer_Guides/06_Testing/00_Unit_Testing.md +++ b/docs/en/02_Developer_Guides/06_Testing/00_Unit_Testing.md @@ -56,7 +56,7 @@ you want to test a `Controller`, `Form` or anything that requires a web page. `FunctionalTest` is a subclass of `SapphireTest` so will inherit all of the behaviors. By subclassing `FunctionalTest` you gain the ability to load and test web pages on the site. -`SapphireTest` in turn, extends `PHPUnit_Framework_TestCase`. For more information on `PHPUnit_Framework_TestCase` see +`SapphireTest` in turn, extends `PHPUnit\Framework\TestCase`. For more information on `PHPUnit\Framework\TestCase` see the [PHPUnit](http://www.phpunit.de) documentation. It provides a lot of fundamental concepts that we build on in this documentation. [/info] @@ -89,9 +89,11 @@ needs. ```xml - - app/tests - + + + app/tests + + sanitychecks @@ -115,7 +117,7 @@ class PageTest extends SapphireTest { protected $usesDatabase = true; - public function setUp() + protected function setUp(): void { parent::setUp(); @@ -152,14 +154,14 @@ use SilverStripe\Dev\SapphireTest; class PageTest extends SapphireTest { - public static function setUpBeforeClass() + public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); // .. } - public static function tearDownAfterClass() + public static function tearDownAfterClass(): void { parent::tearDownAfterClass(); @@ -180,7 +182,7 @@ It's important to remember that the `parent::setUp();` functions will need to be ```php -public static function setUpBeforeClass() +public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); //this will remain for the whole suite and be removed for any other tests diff --git a/docs/en/02_Developer_Guides/06_Testing/How_Tos/00_Write_a_SapphireTest.md b/docs/en/02_Developer_Guides/06_Testing/How_Tos/00_Write_a_SapphireTest.md index 25a3003b7..52368fdbe 100644 --- a/docs/en/02_Developer_Guides/06_Testing/How_Tos/00_Write_a_SapphireTest.md +++ b/docs/en/02_Developer_Guides/06_Testing/How_Tos/00_Write_a_SapphireTest.md @@ -65,9 +65,11 @@ Page: ```xml - - app/tests/ - + + + app/tests/ + + app/src diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 9f66d310f..dbb77b368 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,18 +1,20 @@ - - tests/php - - - tests/php - - - vendor/silverstripe/cms/tests - + + + tests/php + + + tests/php + + + vendor/silverstripe/cms/tests + + . diff --git a/src/Dev/Constraint/SSListContains.php b/src/Dev/Constraint/SSListContains.php index 51eff1785..4929888e7 100644 --- a/src/Dev/Constraint/SSListContains.php +++ b/src/Dev/Constraint/SSListContains.php @@ -4,11 +4,165 @@ namespace SilverStripe\Dev\Constraint; use PHPUnit_Framework_Constraint; use PHPUnit_Framework_ExpectationFailedException; +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; +/* ------------------------------------------------- + * + * This version of SSListContains is for phpunit 9 + * The phpunit 5 version is lower down in this file + * phpunit 6, 7 and 8 are not supported + * + * @see SilverStripe\Dev\SapphireTest + * + * ------------------------------------------------- + */ + +if (class_exists(Constraint::class)) { + + /** + * Constraint for checking if a SS_List contains items matching the given + * key-value pairs. + */ + // Ignore multiple classes in same file + // @codingStandardsIgnoreStart + class SSListContains extends Constraint implements TestOnly + { + // @codingStandardsIgnoreEnd + /** + * @var array + */ + protected $matches = []; + + /** + * Check if the list has left over items that don't match + * + * @var bool + */ + protected $hasLeftoverItems = false; + + public function __construct(array $matches) + { + $this->exporter = new SSListExporter(); + + $this->matches = $matches; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param SS_List $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * + * @return null|bool + * + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false): ?bool + { + $success = true; + + foreach ($other as $item) { + $this->checkIfItemEvaluatesRemainingMatches($item); + } + + //we have remaining matches? + if (count($this->matches) !== 0) { + $success = false; + $this->hasLeftoverItems = true; + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + + return null; + } + + /** + * @param ViewableData $item + * @return bool + */ + protected function checkIfItemEvaluatesRemainingMatches(ViewableData $item): bool + { + $success = false; + foreach ($this->matches as $key => $match) { + $constraint = new ViewableDataContains($match); + + if ($constraint->evaluate($item, '', true)) { + $success = true; + unset($this->matches[$key]); + break; + } + } + + return $success; + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString(): string + { + $matchToString = function ($key, $value) { + return ' "' . $key . '" is "' . $value . '"'; + }; + + $matchesToString = function ($matches) use ($matchToString) { + $matchesAsString = implode(' and ', array_map( + $matchToString, + array_keys($matches), + array_values($matches) + )); + + return '(' . $matchesAsString . ')'; + }; + + $allMatchesAsString = implode( + "\n or ", + array_map($matchesToString, $this->matches) + ); + + + return $this->getStubForToString() . $allMatchesAsString; + } + + /** + * @return string + */ + protected function getStubForToString(): string + { + return ' contains an item matching '; + } + } +} + +/* ------------------------------------------------- + * + * This version of FunctionalTest is for phpunit 5 + * The phpunit 9 verison is at the top of this file + * + * ------------------------------------------------- + */ + if (!class_exists(PHPUnit_Framework_Constraint::class)) { return; } @@ -17,8 +171,11 @@ if (!class_exists(PHPUnit_Framework_Constraint::class)) { * Constraint for checking if a SS_List contains items matching the given * key-value pairs. */ +// Ignore multiple classes in same file +// @codingStandardsIgnoreStart class SSListContains extends PHPUnit_Framework_Constraint implements TestOnly { + // @codingStandardsIgnoreEnd /** * @var array */ @@ -33,7 +190,6 @@ class SSListContains extends PHPUnit_Framework_Constraint implements TestOnly public function __construct($matches) { - parent::__construct(); $this->exporter = new SSListExporter(); $this->matches = $matches; @@ -55,7 +211,7 @@ class SSListContains extends PHPUnit_Framework_Constraint implements TestOnly * * @return null|bool * - * @throws PHPUnit_Framework_ExpectationFailedException + * @throws ExpectationFailedException */ public function evaluate($other, $description = '', $returnResult = false) { @@ -132,6 +288,9 @@ class SSListContains extends PHPUnit_Framework_Constraint implements TestOnly return $this->getStubForToString() . $allMatchesAsString; } + /** + * @return string + */ protected function getStubForToString() { return ' contains an item matching '; diff --git a/src/Dev/Constraint/SSListContainsOnly.php b/src/Dev/Constraint/SSListContainsOnly.php index 0be563ac9..eb11b5370 100644 --- a/src/Dev/Constraint/SSListContainsOnly.php +++ b/src/Dev/Constraint/SSListContainsOnly.php @@ -4,10 +4,21 @@ namespace SilverStripe\Dev\Constraint; use PHPUnit_Framework_Constraint; use PHPUnit_Framework_ExpectationFailedException; +use PHPUnit\Framework\Constraint\Constraint; +use PHPUnit\Framework\ExpectationFailedException; use SilverStripe\Dev\TestOnly; use SilverStripe\ORM\SS_List; -if (!class_exists(PHPUnit_Framework_Constraint::class)) { +/* ------------------------------------------------- + * + * This version of SSListContains is for both phpunit5 and phpunit 9 because it extends SSListContains + * phpunit 6, 7 and 8 are not supported + * + * @see SilverStripe\Dev\SapphireTest + * + * ------------------------------------------------- + */ +if (!class_exists(Constraint::class) && !class_exists(PHPUnit_Framework_Constraint::class)) { return; } @@ -40,9 +51,9 @@ class SSListContainsOnly extends SSListContains implements TestOnly * * @return null|bool * - * @throws PHPUnit_Framework_ExpectationFailedException + * @throws PHPUnit_Framework_ExpectationFailedException|ExpectationFailedException */ - public function evaluate($other, $description = '', $returnResult = false) + public function evaluate($other, $description = '', $returnResult = false): ?bool { $success = true; @@ -71,7 +82,7 @@ class SSListContainsOnly extends SSListContains implements TestOnly return null; } - protected function getStubForToString() + protected function getStubForToString(): string { return $this->itemNotMatching ? parent::getStubForToString() diff --git a/src/Dev/Constraint/SSListContainsOnlyMatchingItems.php b/src/Dev/Constraint/SSListContainsOnlyMatchingItems.php index d17ec07e0..ebacb7658 100644 --- a/src/Dev/Constraint/SSListContainsOnlyMatchingItems.php +++ b/src/Dev/Constraint/SSListContainsOnlyMatchingItems.php @@ -4,20 +4,125 @@ namespace SilverStripe\Dev\Constraint; use PHPUnit_Framework_Constraint; use PHPUnit_Framework_ExpectationFailedException; +use PHPUnit\Framework\Constraint\Constraint; +use PHPUnit\Framework\ExpectationFailedException; use SilverStripe\Dev\SSListExporter; use SilverStripe\Dev\TestOnly; use SilverStripe\ORM\SS_List; +/* ------------------------------------------------- + * + * This version of SSListContainsOnlyMatchingItems is for phpunit 9 + * The phpunit 5 version is lower down in this file + * phpunit 6, 7 and 8 are not supported + * + * @see SilverStripe\Dev\SapphireTest + * + * ------------------------------------------------- + */ + +if (class_exists(Constraint::class)) { + + /** + * Constraint for checking if every item in a SS_List matches a given match, + * e.g. every Member has isActive set to true + */ + // Ignore multiple classes in same file + // @codingStandardsIgnoreStart + class SSListContainsOnlyMatchingItems extends Constraint implements TestOnly + { + // @codingStandardsIgnoreEnd + /** + * @var array + */ + private $match; + + /** + * @var ViewableDataContains + */ + private $constraint; + + public function __construct($match) + { + $this->exporter = new SSListExporter(); + + $this->constraint = new ViewableDataContains($match); + $this->match = $match; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param SS_List $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * + * @return null|bool + * + * @throws ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false): ?bool + { + $success = true; + + foreach ($other as $item) { + if (!$this->constraint->evaluate($item, '', true)) { + $success = false; + break; + } + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + + return null; + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString(): string + { + return 'contains only Objects where "' . key($this->match) . '" is "' . current($this->match) . '"'; + } + } +} + if (!class_exists(PHPUnit_Framework_Constraint::class)) { return; } +/* ------------------------------------------------- + * + * This version of SSListContainsOnlyMatchingItems is for phpunit 5 + * The phpunit 9 verison is at the top of this file + * + * ------------------------------------------------- + */ + /** * Constraint for checking if every item in a SS_List matches a given match, * e.g. every Member has isActive set to true */ +// Ignore multiple classes in same file +// @codingStandardsIgnoreStart class SSListContainsOnlyMatchingItems extends PHPUnit_Framework_Constraint implements TestOnly { + // @codingStandardsIgnoreEnd /** * @var array */ @@ -30,7 +135,6 @@ class SSListContainsOnlyMatchingItems extends PHPUnit_Framework_Constraint imple public function __construct($match) { - parent::__construct(); $this->exporter = new SSListExporter(); $this->constraint = new ViewableDataContains($match); diff --git a/src/Dev/Constraint/ViewableDataContains.php b/src/Dev/Constraint/ViewableDataContains.php index 6665c0f46..015a3deb8 100644 --- a/src/Dev/Constraint/ViewableDataContains.php +++ b/src/Dev/Constraint/ViewableDataContains.php @@ -5,8 +5,117 @@ namespace SilverStripe\Dev\Constraint; use PHPUnit_Framework_Constraint; use PHPUnit_Framework_ExpectationFailedException; use PHPUnit_Util_InvalidArgumentHelper; +use PHPUnit\Framework\Constraint\Constraint; +use PHPUnit\Framework\ExpectationFailedException; use SilverStripe\Dev\TestOnly; use SilverStripe\View\ViewableData; +use SilverStripe\Dev\SapphireTest; + +/* ------------------------------------------------- + * + * This version of ViewableDataContains is for phpunit 9 + * The phpunit 5 version is lower down in this file + * phpunit 6, 7 and 8 are not supported + * + * @see SilverStripe\Dev\SapphireTest + * + * ------------------------------------------------- + */ + +if (class_exists(Constraint::class)) { + + /** + * Constraint for checking if a ViewableData (e.g. ArrayData or any DataObject) contains fields matching the given + * key-value pairs. + */ + // Ignore multiple classes in same file + // @codingStandardsIgnoreStart + class ViewableDataContains extends Constraint implements TestOnly + { + // @codingStandardsIgnoreEnd + /** + * @var array + */ + private $match; + + /** + * ViewableDataContains constructor. + * @param array $match + */ + public function __construct(array $match) + { + if (!is_array($match)) { + throw SapphireTest::createInvalidArgumentException( + 1, + 'array' + ); + } + + $this->match = $match; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param ViewableData $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * + * @return null|bool + * + * @throws ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false): ?bool + { + $success = true; + + foreach ($this->match as $fieldName => $value) { + if ($other->$fieldName != $value) { + $success = false; + break; + } + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + + return null; + } + + + /** + * Returns a string representation of the object. + * + * @todo: add representation for more than one match + * + * @return string + */ + public function toString(): string + { + return 'contains only Objects where "' . key($this->match) . '" is "' . current($this->match) . '"'; + } + } +} + +/* ------------------------------------------------- + * + * This version of ViewableDataContains is for phpunit 5 + * The phpunit 9 verison is at the top of this file + * + * ------------------------------------------------- + */ if (!class_exists(PHPUnit_Framework_Constraint::class)) { return; @@ -16,8 +125,11 @@ if (!class_exists(PHPUnit_Framework_Constraint::class)) { * Constraint for checking if a ViewableData (e.g. ArrayData or any DataObject) contains fields matching the given * key-value pairs. */ +// Ignore multiple classes in same file +// @codingStandardsIgnoreStart class ViewableDataContains extends PHPUnit_Framework_Constraint implements TestOnly { + // @codingStandardsIgnoreEnd /** * @var array */ @@ -30,7 +142,6 @@ class ViewableDataContains extends PHPUnit_Framework_Constraint implements TestO public function __construct($match) { parent::__construct(); - if (!is_array($match)) { throw PHPUnit_Util_InvalidArgumentHelper::factory( 1, @@ -81,7 +192,6 @@ class ViewableDataContains extends PHPUnit_Framework_Constraint implements TestO return null; } - /** * Returns a string representation of the object. * diff --git a/src/Dev/FunctionalTest.php b/src/Dev/FunctionalTest.php index 0d9e7459d..fb9ae78ab 100644 --- a/src/Dev/FunctionalTest.php +++ b/src/Dev/FunctionalTest.php @@ -3,6 +3,9 @@ namespace SilverStripe\Dev; use PHPUnit_Framework_AssertionFailedError; +use PHPUnit_Extensions_GroupTestSuite; +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\Constraint\IsEqualCanonicalizing; use SilverStripe\Control\Director; use SilverStripe\Control\HTTPResponse; use SilverStripe\Control\Session; @@ -12,6 +15,463 @@ use SilverStripe\Security\SecurityToken; use SilverStripe\View\SSViewer; use SimpleXMLElement; +/* ------------------------------------------------- + * + * This version of FunctionalTest is for phpunit 9 + * The phpunit 5 version is lower down in this file + * phpunit 6, 7 and 8 are not supported + * + * @see SilverStripe\Dev\SapphireTest + * + * IsEqualCanonicalizing::class is a new class added in PHPUnit 9, testing that this class exists + * to ensure that we're not using a a prior, incompatible version of PHPUnit + * + * ------------------------------------------------- + */ +if (class_exists(IsEqualCanonicalizing::class)) { + + /** + * SilverStripe-specific testing object designed to support functional testing of your web app. It simulates get/post + * requests, form submission, and can validate resulting HTML, looking up content by CSS selector. + * + * The example below shows how it works. + * + * + * public function testMyForm() { + * // Visit a URL + * $this->get("your/url"); + * + * // Submit a form on the page that you get in response + * $this->submitForm("MyForm_ID", "action_dologin", array("Email" => "invalid email ^&*&^")); + * + * // Validate the content that is returned + * $this->assertExactMatchBySelector("#MyForm_ID p.error", array("That email address is invalid.")); + * } + * + */ + // Ignore multiple classes in same file + // @codingStandardsIgnoreStart + class FunctionalTest extends SapphireTest implements TestOnly + { + // @codingStandardsIgnoreEnd + /** + * Set this to true on your sub-class to disable the use of themes in this test. + * This can be handy for functional testing of modules without having to worry about whether a user has changed + * behaviour by replacing the theme. + * + * @var bool + */ + protected static $disable_themes = false; + + /** + * Set this to true on your sub-class to use the draft site by default for every test in this class. + * + * @deprecated 4.2.0:5.0.0 Use ?stage=Stage in your ->get() querystring requests instead + * @var bool + */ + protected static $use_draft_site = false; + + /** + * @var TestSession + */ + protected $mainSession = null; + + /** + * CSSContentParser for the most recently requested page. + * + * @var CSSContentParser + */ + protected $cssParser = null; + + /** + * If this is true, then 30x Location headers will be automatically followed. + * If not, then you will have to manaully call $this->mainSession->followRedirection() to follow them. + * However, this will let you inspect the intermediary headers + * + * @var bool + */ + protected $autoFollowRedirection = true; + + /** + * Returns the {@link Session} object for this test + * + * @return Session + */ + public function session() + { + return $this->mainSession->session(); + } + + protected function setUp(): void + { + parent::setUp(); + + // Skip calling FunctionalTest directly. + if (static::class == __CLASS__) { + $this->markTestSkipped(sprintf('Skipping %s ', static::class)); + } + + $this->mainSession = new TestSession(); + + // Disable theme, if necessary + if (static::get_disable_themes()) { + SSViewer::config()->update('theme_enabled', false); + } + + // Flush user + $this->logOut(); + + // Switch to draft site, if necessary + // If you rely on this you should be crafting stage-specific urls instead though. + if (static::get_use_draft_site()) { + $this->useDraftSite(); + } + + // Unprotect the site, tests are running with the assumption it's off. They will enable it on a case-by-case + // basis. + BasicAuth::protect_entire_site(false); + + SecurityToken::disable(); + } + + protected function tearDown(): void + { + SecurityToken::enable(); + unset($this->mainSession); + parent::tearDown(); + } + + /** + * Run a test while mocking the base url with the provided value + * @param string $url The base URL to use for this test + * @param callable $callback The test to run + */ + protected function withBaseURL($url, $callback) + { + $oldBase = Config::inst()->get(Director::class, 'alternate_base_url'); + Config::modify()->set(Director::class, 'alternate_base_url', $url); + $callback($this); + Config::modify()->set(Director::class, 'alternate_base_url', $oldBase); + } + + /** + * Run a test while mocking the base folder with the provided value + * @param string $folder The base folder to use for this test + * @param callable $callback The test to run + */ + protected function withBaseFolder($folder, $callback) + { + $oldFolder = Config::inst()->get(Director::class, 'alternate_base_folder'); + Config::modify()->set(Director::class, 'alternate_base_folder', $folder); + $callback($this); + Config::modify()->set(Director::class, 'alternate_base_folder', $oldFolder); + } + + /** + * Submit a get request + * @uses Director::test() + * + * @param string $url + * @param Session $session + * @param array $headers + * @param array $cookies + * @return HTTPResponse + */ + public function get($url, $session = null, $headers = null, $cookies = null) + { + $this->cssParser = null; + $response = $this->mainSession->get($url, $session, $headers, $cookies); + if ($this->autoFollowRedirection && is_object($response) && $response->getHeader('Location')) { + $response = $this->mainSession->followRedirection(); + } + return $response; + } + + /** + * Submit a post request + * + * @uses Director::test() + * @param string $url + * @param array $data + * @param array $headers + * @param Session $session + * @param string $body + * @param array $cookies + * @return HTTPResponse + */ + public function post($url, $data, $headers = null, $session = null, $body = null, $cookies = null) + { + $this->cssParser = null; + $response = $this->mainSession->post($url, $data, $headers, $session, $body, $cookies); + if ($this->autoFollowRedirection && is_object($response) && $response->getHeader('Location')) { + $response = $this->mainSession->followRedirection(); + } + return $response; + } + + /** + * Submit the form with the given HTML ID, filling it out with the given data. + * Acts on the most recent response. + * + * Any data parameters have to be present in the form, with exact form field name + * and values, otherwise they are removed from the submission. + * + * Caution: Parameter names have to be formatted + * as they are in the form submission, not as they are interpreted by PHP. + * Wrong: array('mycheckboxvalues' => array(1 => 'one', 2 => 'two')) + * Right: array('mycheckboxvalues[1]' => 'one', 'mycheckboxvalues[2]' => 'two') + * + * @see http://www.simpletest.org/en/form_testing_documentation.html + * + * @param string $formID HTML 'id' attribute of a form (loaded through a previous response) + * @param string $button HTML 'name' attribute of the button (NOT the 'id' attribute) + * @param array $data Map of GET/POST data. + * @return HTTPResponse + */ + public function submitForm($formID, $button = null, $data = []) + { + $this->cssParser = null; + $response = $this->mainSession->submitForm($formID, $button, $data); + if ($this->autoFollowRedirection && is_object($response) && $response->getHeader('Location')) { + $response = $this->mainSession->followRedirection(); + } + return $response; + } + + /** + * Return the most recent content + * + * @return string + */ + public function content() + { + return $this->mainSession->lastContent(); + } + + /** + * Find an attribute in a SimpleXMLElement object by name. + * @param SimpleXMLElement $object + * @param string $attribute Name of attribute to find + * @return SimpleXMLElement object of the attribute + */ + public function findAttribute($object, $attribute) + { + $found = false; + foreach ($object->attributes() as $a => $b) { + if ($a == $attribute) { + $found = $b; + } + } + return $found; + } + + /** + * Return a CSSContentParser for the most recent content. + * + * @return CSSContentParser + */ + public function cssParser() + { + if (!$this->cssParser) { + $this->cssParser = new CSSContentParser($this->mainSession->lastContent()); + } + return $this->cssParser; + } + + /** + * Assert that the most recently queried page contains a number of content tags specified by a CSS selector. + * The given CSS selector will be applied to the HTML of the most recent page. The content of every matching tag + * will be examined. The assertion fails if one of the expectedMatches fails to appear. + * + * Note:   characters are stripped from the content; make sure that your assertions take this into account. + * + * @param string $selector A basic CSS selector, e.g. 'li.jobs h3' + * @param array|string $expectedMatches The content of at least one of the matched tags + * @param string $message + * @throws AssertionFailedError + */ + public function assertPartialMatchBySelector($selector, $expectedMatches, $message = null) + { + if (is_string($expectedMatches)) { + $expectedMatches = [$expectedMatches]; + } + + $items = $this->cssParser()->getBySelector($selector); + + $actuals = []; + if ($items) { + foreach ($items as $item) { + $actuals[trim(preg_replace('/\s+/', ' ', (string)$item))] = true; + } + } + + $message = $message ?: + "Failed asserting the CSS selector '$selector' has a partial match to the expected elements:\n'" + . implode("'\n'", $expectedMatches) . "'\n\n" + . "Instead the following elements were found:\n'" . implode("'\n'", array_keys($actuals)) . "'"; + + foreach ($expectedMatches as $match) { + $this->assertTrue(isset($actuals[$match]), $message); + } + } + + /** + * Assert that the most recently queried page contains a number of content tags specified by a CSS selector. + * The given CSS selector will be applied to the HTML of the most recent page. The full HTML of every matching tag + * will be examined. The assertion fails if one of the expectedMatches fails to appear. + * + * Note:   characters are stripped from the content; make sure that your assertions take this into account. + * + * @param string $selector A basic CSS selector, e.g. 'li.jobs h3' + * @param array|string $expectedMatches The content of *all* matching tags as an array + * @param string $message + * @throws AssertionFailedError + */ + public function assertExactMatchBySelector($selector, $expectedMatches, $message = null) + { + if (is_string($expectedMatches)) { + $expectedMatches = [$expectedMatches]; + } + + $items = $this->cssParser()->getBySelector($selector); + + $actuals = []; + if ($items) { + foreach ($items as $item) { + $actuals[] = trim(preg_replace('/\s+/', ' ', (string)$item)); + } + } + + $message = $message ?: + "Failed asserting the CSS selector '$selector' has an exact match to the expected elements:\n'" + . implode("'\n'", $expectedMatches) . "'\n\n" + . "Instead the following elements were found:\n'" . implode("'\n'", $actuals) . "'"; + + $this->assertTrue($expectedMatches == $actuals, $message); + } + + /** + * Assert that the most recently queried page contains a number of content tags specified by a CSS selector. + * The given CSS selector will be applied to the HTML of the most recent page. The content of every matching tag + * will be examined. The assertion fails if one of the expectedMatches fails to appear. + * + * Note:   characters are stripped from the content; make sure that your assertions take this into account. + * + * @param string $selector A basic CSS selector, e.g. 'li.jobs h3' + * @param array|string $expectedMatches The content of at least one of the matched tags + * @param string $message + * @throws AssertionFailedError + */ + public function assertPartialHTMLMatchBySelector($selector, $expectedMatches, $message = null) + { + if (is_string($expectedMatches)) { + $expectedMatches = [$expectedMatches]; + } + + $items = $this->cssParser()->getBySelector($selector); + + $actuals = []; + if ($items) { + /** @var SimpleXMLElement $item */ + foreach ($items as $item) { + $actuals[$item->asXML()] = true; + } + } + + $message = $message ?: + "Failed asserting the CSS selector '$selector' has a partial match to the expected elements:\n'" + . implode("'\n'", $expectedMatches) . "'\n\n" + . "Instead the following elements were found:\n'" . implode("'\n'", array_keys($actuals)) . "'"; + + foreach ($expectedMatches as $match) { + $this->assertTrue(isset($actuals[$match]), $message); + } + } + + /** + * Assert that the most recently queried page contains a number of content tags specified by a CSS selector. + * The given CSS selector will be applied to the HTML of the most recent page. The full HTML of every matching tag + * will be examined. The assertion fails if one of the expectedMatches fails to appear. + * + * Note:   characters are stripped from the content; make sure that your assertions take this into account. + * + * @param string $selector A basic CSS selector, e.g. 'li.jobs h3' + * @param array|string $expectedMatches The content of *all* matched tags as an array + * @param string $message + * @throws AssertionFailedError + */ + public function assertExactHTMLMatchBySelector($selector, $expectedMatches, $message = null) + { + $items = $this->cssParser()->getBySelector($selector); + + $actuals = []; + if ($items) { + /** @var SimpleXMLElement $item */ + foreach ($items as $item) { + $actuals[] = $item->asXML(); + } + } + + $message = $message ?: + "Failed asserting the CSS selector '$selector' has an exact match to the expected elements:\n'" + . implode("'\n'", $expectedMatches) . "'\n\n" + . "Instead the following elements were found:\n'" . implode("'\n'", $actuals) . "'"; + + $this->assertTrue($expectedMatches == $actuals, $message); + } + + /** + * Use the draft (stage) site for testing. + * This is helpful if you're not testing publication functionality and don't want "stage management" cluttering + * your test. + * + * @deprecated 4.2.0:5.0.0 Use ?stage=Stage querystring arguments instead of useDraftSite + * @param bool $enabled toggle the use of the draft site + */ + public function useDraftSite($enabled = true) + { + Deprecation::notice('5.0', 'Use ?stage=Stage querystring arguments instead of useDraftSite'); + if ($enabled) { + $this->session()->set('readingMode', 'Stage.Stage'); + $this->session()->set('unsecuredDraftSite', true); + } else { + $this->session()->clear('readingMode'); + $this->session()->clear('unsecuredDraftSite'); + } + } + + /** + * @return bool + */ + public static function get_disable_themes() + { + return static::$disable_themes; + } + + /** + * @deprecated 4.2.0:5.0.0 Use ?stage=Stage in your querystring arguments instead + * @return bool + */ + public static function get_use_draft_site() + { + return static::$use_draft_site; + } + } +} + +/* ------------------------------------------------- + * + * This version of FunctionalTest is for PHPUnit 5 + * The PHPUnit 9 version is at the top of this file + * + * PHPUnit_Extensions_GroupTestSuite is a class that only exists in PHPUnit 5 + * + * ------------------------------------------------- + */ +if (!class_exists(PHPUnit_Extensions_GroupTestSuite::class)) { + return; +} + /** * SilverStripe-specific testing object designed to support functional testing of your web app. It simulates get/post * requests, form submission, and can validate resulting HTML, looking up content by CSS selector. @@ -31,8 +491,11 @@ use SimpleXMLElement; * } * */ +// Ignore multiple classes in same file +// @codingStandardsIgnoreStart class FunctionalTest extends SapphireTest implements TestOnly { + // @codingStandardsIgnoreEnd /** * Set this to true on your sub-class to disable the use of themes in this test. * This can be handy for functional testing of modules without having to worry about whether a user has changed diff --git a/src/Dev/SapphireTest.php b/src/Dev/SapphireTest.php index fb987006b..2a0d24622 100644 --- a/src/Dev/SapphireTest.php +++ b/src/Dev/SapphireTest.php @@ -1,12 +1,21 @@ " notation + * between the fixtures, they act independent of each other. + * + * @var string|array + */ + protected static $fixture_file = null; + + /** + * @deprecated 4.0..5.0 Use FixtureTestState instead + * @var FixtureFactory + */ + protected $fixtureFactory; + + /** + * @var Boolean If set to TRUE, this will force a test database to be generated + * in {@link setUp()}. Note that this flag is overruled by the presence of a + * {@link $fixture_file}, which always forces a database build. + * + * @var bool + */ + protected $usesDatabase = null; + + /** + * This test will cleanup its state via transactions. + * If set to false a full schema is forced between tests, but at a performance cost. + * + * @var bool + */ + protected $usesTransactions = true; + + /** + * @var bool + */ + protected static $is_running_test = false; + + /** + * By default, setUp() does not require default records. Pass + * class names in here, and the require/augment default records + * function will be called on them. + * + * @var array + */ + protected $requireDefaultRecordsFrom = []; + + /** + * A list of extensions that can't be applied during the execution of this run. If they are + * applied, they will be temporarily removed and a database migration called. + * + * The keys of the are the classes that the extensions can't be applied the extensions to, and + * the values are an array of illegal extensions on that class. + * + * Set a class to `*` to remove all extensions (unadvised) + * + * @var array + */ + protected static $illegal_extensions = []; + + /** + * A list of extensions that must be applied during the execution of this run. If they are + * not applied, they will be temporarily added and a database migration called. + * + * The keys of the are the classes to apply the extensions to, and the values are an array + * of required extensions on that class. + * + * Example: + * + * array("MyTreeDataObject" => array("Versioned", "Hierarchy")) + * + * + * @var array + */ + protected static $required_extensions = []; + + /** + * By default, the test database won't contain any DataObjects that have the interface TestOnly. + * This variable lets you define additional TestOnly DataObjects to set up for this test. + * Set it to an array of DataObject subclass names. + * + * @var array + */ + protected static $extra_dataobjects = []; + + /** + * List of class names of {@see Controller} objects to register routes for + * Controllers must implement Link() method + * + * @var array + */ + protected static $extra_controllers = []; + + /** + * We need to disabling backing up of globals to avoid overriding + * the few globals SilverStripe relies on, like $lang for the i18n subsystem. + * + * @see http://sebastian-bergmann.de/archives/797-Global-Variables-and-PHPUnit.html + */ + protected $backupGlobals = false; + + /** + * State management container for SapphireTest + * + * @var SapphireTestState + */ + protected static $state = null; + + /** + * Temp database helper + * + * @var TempDatabase + */ + protected static $tempDB = null; + + /** + * @return TempDatabase + */ + public static function tempDB() + { + if (!class_exists(TempDatabase::class)) { + return null; + } + + if (!static::$tempDB) { + static::$tempDB = TempDatabase::create(); + } + return static::$tempDB; + } + + /** + * Gets illegal extensions for this class + * + * @return array + */ + public static function getIllegalExtensions() + { + return static::$illegal_extensions; + } + + /** + * Gets required extensions for this class + * + * @return array + */ + public static function getRequiredExtensions() + { + return static::$required_extensions; + } + + /** + * Check if test bootstrapping has been performed. Must not be relied on + * outside of unit tests. + * + * @return bool + */ + protected static function is_running_test() + { + return self::$is_running_test; + } + + /** + * Set test running state + * + * @param bool $bool + */ + protected static function set_is_running_test($bool) + { + self::$is_running_test = $bool; + } + + /** + * @return String + */ + public static function get_fixture_file() + { + return static::$fixture_file; + } + + /** + * @return bool + */ + public function getUsesDatabase() + { + return $this->usesDatabase; + } + + /** + * @return bool + */ + public function getUsesTransactions() + { + return $this->usesTransactions; + } + + /** + * @return array + */ + public function getRequireDefaultRecordsFrom() + { + return $this->requireDefaultRecordsFrom; + } + + /** + * Setup the test. + * Always sets up in order: + * - Reset php state + * - Nest + * - Custom state helpers + * + * User code should call parent::setUp() before custom setup code + */ + protected function setUp(): void + { + if (!defined('FRAMEWORK_PATH')) { + trigger_error( + 'Missing constants, did you remember to include the test bootstrap in your phpunit.xml file?', + E_USER_WARNING + ); + } + + // Call state helpers + static::$state->setUp($this); + + // We cannot run the tests on this abstract class. + if (static::class == __CLASS__) { + $this->markTestSkipped(sprintf('Skipping %s ', static::class)); + } + + // i18n needs to be set to the defaults or tests fail + if (class_exists(i18n::class)) { + i18n::set_locale(i18n::config()->uninherited('default_locale')); + } + + // Set default timezone consistently to avoid NZ-specific dependencies + date_default_timezone_set('UTC'); + + if (class_exists(Member::class)) { + Member::set_password_validator(null); + } + + if (class_exists(Cookie::class)) { + Cookie::config()->update('report_errors', false); + } + + if (class_exists(RootURLController::class)) { + RootURLController::reset(); + } + + if (class_exists(Security::class)) { + Security::clear_database_is_ready(); + } + + // Set up test routes + $this->setUpRoutes(); + + $fixtureFiles = $this->getFixturePaths(); + + if ($this->shouldSetupDatabaseForCurrentTest($fixtureFiles)) { + // Assign fixture factory to deprecated prop in case old tests use it over the getter + /** @var FixtureTestState $fixtureState */ + $fixtureState = static::$state->getStateByName('fixtures'); + $this->fixtureFactory = $fixtureState->getFixtureFactory(static::class); + + $this->logInWithPermission('ADMIN'); + } + + // turn off template debugging + if (class_exists(SSViewer::class)) { + SSViewer::config()->update('source_file_comments', false); + } + + // Set up the test mailer + if (class_exists(TestMailer::class)) { + Injector::inst()->registerService(new TestMailer(), Mailer::class); + } + + if (class_exists(Email::class)) { + Email::config()->remove('send_all_emails_to'); + Email::config()->remove('send_all_emails_from'); + Email::config()->remove('cc_all_emails_to'); + Email::config()->remove('bcc_all_emails_to'); + } + } + + + /** + * Helper method to determine if the current test should enable a test database + * + * @param $fixtureFiles + * @return bool + */ + protected function shouldSetupDatabaseForCurrentTest($fixtureFiles) + { + $databaseEnabledByDefault = $fixtureFiles || $this->usesDatabase; + + return ($databaseEnabledByDefault && !$this->currentTestDisablesDatabase()) + || $this->currentTestEnablesDatabase(); + } + + /** + * Helper method to check, if the current test uses the database. + * This can be switched on with the annotation "@useDatabase" + * + * @return bool + */ + protected function currentTestEnablesDatabase() + { + $annotations = $this->getAnnotations(); + + return array_key_exists('useDatabase', $annotations['method']) + && $annotations['method']['useDatabase'][0] !== 'false'; + } + + /** + * Helper method to check, if the current test uses the database. + * This can be switched on with the annotation "@useDatabase false" + * + * @return bool + */ + protected function currentTestDisablesDatabase() + { + $annotations = $this->getAnnotations(); + + return array_key_exists('useDatabase', $annotations['method']) + && $annotations['method']['useDatabase'][0] === 'false'; + } + + /** + * Called once per test case ({@link SapphireTest} subclass). + * This is different to {@link setUp()}, which gets called once + * per method. Useful to initialize expensive operations which + * don't change state for any called method inside the test, + * e.g. dynamically adding an extension. See {@link teardownAfterClass()} + * for tearing down the state again. + * + * Always sets up in order: + * - Reset php state + * - Nest + * - Custom state helpers + * + * User code should call parent::setUpBeforeClass() before custom setup code + * + * @throws Exception + */ + public static function setUpBeforeClass(): void + { + // Start tests + static::start(); + + if (!static::$state) { + throw new Exception('SapphireTest failed to bootstrap!'); + } + + // Call state helpers + static::$state->setUpOnce(static::class); + + // Build DB if we have objects + if (class_exists(DataObject::class) && static::getExtraDataObjects()) { + DataObject::reset(); + static::resetDBSchema(true, true); + } + } + + /** + * tearDown method that's called once per test class rather once per test method. + * + * Always sets up in order: + * - Custom state helpers + * - Unnest + * - Reset php state + * + * User code should call parent::tearDownAfterClass() after custom tear down code + */ + public static function tearDownAfterClass(): void + { + // Call state helpers + static::$state->tearDownOnce(static::class); + + // Reset DB schema + static::resetDBSchema(); + } + + /** + * @return FixtureFactory|false + * @deprecated 4.0.0:5.0.0 + */ + public function getFixtureFactory() + { + Deprecation::notice('5.0', __FUNCTION__ . ' is deprecated, use ' . FixtureTestState::class . ' instead'); + /** @var FixtureTestState $state */ + $state = static::$state->getStateByName('fixtures'); + return $state->getFixtureFactory(static::class); + } + + /** + * Sets a new fixture factory + * @param FixtureFactory $factory + * @return $this + * @deprecated 4.0.0:5.0.0 + */ + public function setFixtureFactory(FixtureFactory $factory) + { + Deprecation::notice('5.0', __FUNCTION__ . ' is deprecated, use ' . FixtureTestState::class . ' instead'); + /** @var FixtureTestState $state */ + $state = static::$state->getStateByName('fixtures'); + $state->setFixtureFactory($factory, static::class); + $this->fixtureFactory = $factory; + return $this; + } + + /** + * Get the ID of an object from the fixture. + * + * @param string $className The data class or table name, as specified in your fixture file. Parent classes won't work + * @param string $identifier The identifier string, as provided in your fixture file + * @return int + */ + protected function idFromFixture($className, $identifier) + { + /** @var FixtureTestState $state */ + $state = static::$state->getStateByName('fixtures'); + $id = $state->getFixtureFactory(static::class)->getId($className, $identifier); + + if (!$id) { + throw new InvalidArgumentException(sprintf( + "Couldn't find object '%s' (class: %s)", + $identifier, + $className + )); + } + + return $id; + } + + /** + * Return all of the IDs in the fixture of a particular class name. + * Will collate all IDs form all fixtures if multiple fixtures are provided. + * + * @param string $className The data class or table name, as specified in your fixture file + * @return array A map of fixture-identifier => object-id + */ + protected function allFixtureIDs($className) + { + /** @var FixtureTestState $state */ + $state = static::$state->getStateByName('fixtures'); + return $state->getFixtureFactory(static::class)->getIds($className); + } + + /** + * Get an object from the fixture. + * + * @param string $className The data class or table name, as specified in your fixture file. Parent classes won't work + * @param string $identifier The identifier string, as provided in your fixture file + * + * @return DataObject + */ + protected function objFromFixture($className, $identifier) + { + /** @var FixtureTestState $state */ + $state = static::$state->getStateByName('fixtures'); + $obj = $state->getFixtureFactory(static::class)->get($className, $identifier); + + if (!$obj) { + throw new InvalidArgumentException(sprintf( + "Couldn't find object '%s' (class: %s)", + $identifier, + $className + )); + } + + return $obj; + } + + /** + * Load a YAML fixture file into the database. + * Once loaded, you can use idFromFixture() and objFromFixture() to get items from the fixture. + * Doesn't clear existing fixtures. + * @param string $fixtureFile The location of the .yml fixture file, relative to the site base dir + * @deprecated 4.0.0:5.0.0 + * + */ + public function loadFixture($fixtureFile) + { + Deprecation::notice('5.0', __FUNCTION__ . ' is deprecated, use ' . FixtureTestState::class . ' instead'); + $fixture = Injector::inst()->create(YamlFixture::class, $fixtureFile); + $fixture->writeInto($this->getFixtureFactory()); + } + + /** + * Clear all fixtures which were previously loaded through + * {@link loadFixture()} + */ + public function clearFixtures() + { + /** @var FixtureTestState $state */ + $state = static::$state->getStateByName('fixtures'); + $state->getFixtureFactory(static::class)->clear(); + } + + /** + * Useful for writing unit tests without hardcoding folder structures. + * + * @return string Absolute path to current class. + */ + protected function getCurrentAbsolutePath() + { + $filename = ClassLoader::inst()->getItemPath(static::class); + if (!$filename) { + throw new LogicException('getItemPath returned null for ' . static::class + . '. Try adding flush=1 to the test run.'); + } + return dirname($filename); + } + + /** + * @return string File path relative to webroot + */ + protected function getCurrentRelativePath() + { + $base = Director::baseFolder(); + $path = $this->getCurrentAbsolutePath(); + if (substr($path, 0, strlen($base)) == $base) { + $path = preg_replace('/^\/*/', '', substr($path, strlen($base))); + } + return $path; + } + + /** + * Setup the test. + * Always sets up in order: + * - Custom state helpers + * - Unnest + * - Reset php state + * + * User code should call parent::tearDown() after custom tear down code + */ + protected function tearDown(): void + { + // Reset mocked datetime + if (class_exists(DBDatetime::class)) { + DBDatetime::clear_mock_now(); + } + + // Stop the redirection that might have been requested in the test. + // Note: Ideally a clean Controller should be created for each test. + // Now all tests executed in a batch share the same controller. + if (class_exists(Controller::class)) { + $controller = Controller::has_curr() ? Controller::curr() : null; + if ($controller && ($response = $controller->getResponse()) && $response->getHeader('Location')) { + $response->setStatusCode(200); + $response->removeHeader('Location'); + } + } + + // Call state helpers + static::$state->tearDown($this); + } + + /** + * Clear the log of emails sent + * + * @return bool True if emails cleared + */ + public function clearEmails() + { + /** @var Mailer $mailer */ + $mailer = Injector::inst()->get(Mailer::class); + if ($mailer instanceof TestMailer) { + $mailer->clearEmails(); + return true; + } + return false; + } + + /** + * Search for an email that was sent. + * All of the parameters can either be a string, or, if they start with "/", a PREG-compatible regular expression. + * @param string $to + * @param string $from + * @param string $subject + * @param string $content + * @return array|null Contains keys: 'Type', 'To', 'From', 'Subject', 'Content', 'PlainContent', 'AttachedFiles', + * 'HtmlContent' + */ + public static function findEmail($to, $from = null, $subject = null, $content = null) + { + /** @var Mailer $mailer */ + $mailer = Injector::inst()->get(Mailer::class); + if ($mailer instanceof TestMailer) { + return $mailer->findEmail($to, $from, $subject, $content); + } + return null; + } + + /** + * Assert that the matching email was sent since the last call to clearEmails() + * All of the parameters can either be a string, or, if they start with "/", a PREG-compatible regular expression. + * + * @param string $to + * @param string $from + * @param string $subject + * @param string $content + */ + public static function assertEmailSent($to, $from = null, $subject = null, $content = null) + { + $found = (bool)static::findEmail($to, $from, $subject, $content); + + $infoParts = ''; + $withParts = []; + if ($to) { + $infoParts .= " to '$to'"; + } + if ($from) { + $infoParts .= " from '$from'"; + } + if ($subject) { + $withParts[] = "subject '$subject'"; + } + if ($content) { + $withParts[] = "content '$content'"; + } + if ($withParts) { + $infoParts .= ' with ' . implode(' and ', $withParts); + } + + static::assertTrue( + $found, + "Failed asserting that an email was sent$infoParts." + ); + } + + + /** + * Assert that the given {@link SS_List} includes DataObjects matching the given key-value + * pairs. Each match must correspond to 1 distinct record. + * + * @param SS_List|array $matches The patterns to match. Each pattern is a map of key-value pairs. You can + * either pass a single pattern or an array of patterns. + * @param SS_List $list The {@link SS_List} to test. + * @param string $message + * + * Examples + * -------- + * Check that $members includes an entry with Email = sam@example.com: + * $this->assertListContains(['Email' => '...@example.com'], $members); + * + * Check that $members includes entries with Email = sam@example.com and with + * Email = ingo@example.com: + * $this->assertListContains([ + * ['Email' => '...@example.com'], + * ['Email' => 'i...@example.com'], + * ], $members); + */ + public static function assertListContains($matches, SS_List $list, $message = '') + { + if (!is_array($matches)) { + throw self::createInvalidArgumentException( + 1, + 'array' + ); + } + + static::assertThat( + $list, + new SSListContains( + $matches + ), + $message + ); + } + + /** + * @param $matches + * @param $dataObjectSet + * @deprecated 4.0.0:5.0.0 Use assertListContains() instead + * + */ + public function assertDOSContains($matches, $dataObjectSet) + { + Deprecation::notice('5.0', 'Use assertListContains() instead'); + static::assertListContains($matches, $dataObjectSet); + } + + /** + * Asserts that no items in a given list appear in the given dataobject list + * + * @param SS_List|array $matches The patterns to match. Each pattern is a map of key-value pairs. You can + * either pass a single pattern or an array of patterns. + * @param SS_List $list The {@link SS_List} to test. + * @param string $message + * + * Examples + * -------- + * Check that $members doesn't have an entry with Email = sam@example.com: + * $this->assertListNotContains(['Email' => '...@example.com'], $members); + * + * Check that $members doesn't have entries with Email = sam@example.com and with + * Email = ingo@example.com: + * $this->assertListNotContains([ + * ['Email' => '...@example.com'], + * ['Email' => 'i...@example.com'], + * ], $members); + */ + public static function assertListNotContains($matches, SS_List $list, $message = '') + { + if (!is_array($matches)) { + throw self::createInvalidArgumentException( + 1, + 'array' + ); + } + + $constraint = new LogicalNot( + new SSListContains( + $matches + ) + ); + + static::assertThat( + $list, + $constraint, + $message + ); + } + + /** + * @param $matches + * @param $dataObjectSet + * @deprecated 4.0.0:5.0.0 Use assertListNotContains() instead + * + */ + public static function assertNotDOSContains($matches, $dataObjectSet) + { + Deprecation::notice('5.0', 'Use assertListNotContains() instead'); + static::assertListNotContains($matches, $dataObjectSet); + } + + /** + * Assert that the given {@link SS_List} includes only DataObjects matching the given + * key-value pairs. Each match must correspond to 1 distinct record. + * + * Example + * -------- + * Check that *only* the entries Sam Minnee and Ingo Schommer exist in $members. Order doesn't + * matter: + * $this->assertListEquals([ + * ['FirstName' =>'Sam', 'Surname' => 'Minnee'], + * ['FirstName' => 'Ingo', 'Surname' => 'Schommer'], + * ], $members); + * + * @param mixed $matches The patterns to match. Each pattern is a map of key-value pairs. You can + * either pass a single pattern or an array of patterns. + * @param mixed $list The {@link SS_List} to test. + * @param string $message + */ + public static function assertListEquals($matches, SS_List $list, $message = '') + { + if (!is_array($matches)) { + throw self::createInvalidArgumentException( + 1, + 'array' + ); + } + + static::assertThat( + $list, + new SSListContainsOnly( + $matches + ), + $message + ); + } + + /** + * @param $matches + * @param SS_List $dataObjectSet + * @deprecated 4.0.0:5.0.0 Use assertListEquals() instead + * + */ + public function assertDOSEquals($matches, $dataObjectSet) + { + Deprecation::notice('5.0', 'Use assertListEquals() instead'); + static::assertListEquals($matches, $dataObjectSet); + } + + + /** + * Assert that the every record in the given {@link SS_List} matches the given key-value + * pairs. + * + * Example + * -------- + * Check that every entry in $members has a Status of 'Active': + * $this->assertListAllMatch(['Status' => 'Active'], $members); + * + * @param mixed $match The pattern to match. The pattern is a map of key-value pairs. + * @param mixed $list The {@link SS_List} to test. + * @param string $message + */ + public static function assertListAllMatch($match, SS_List $list, $message = '') + { + if (!is_array($match)) { + throw self::createInvalidArgumentException( + 1, + 'array' + ); + } + + static::assertThat( + $list, + new SSListContainsOnlyMatchingItems( + $match + ), + $message + ); + } + + /** + * @param $match + * @param SS_List $dataObjectSet + * @deprecated 4.0.0:5.0.0 Use assertListAllMatch() instead + * + */ + public function assertDOSAllMatch($match, SS_List $dataObjectSet) + { + Deprecation::notice('5.0', 'Use assertListAllMatch() instead'); + static::assertListAllMatch($match, $dataObjectSet); + } + + /** + * Removes sequences of repeated whitespace characters from SQL queries + * making them suitable for string comparison + * + * @param string $sql + * @return string The cleaned and normalised SQL string + */ + protected static function normaliseSQL($sql) + { + return trim(preg_replace('/\s+/m', ' ', $sql)); + } + + /** + * Asserts that two SQL queries are equivalent + * + * @param string $expectedSQL + * @param string $actualSQL + * @param string $message + */ + public static function assertSQLEquals( + $expectedSQL, + $actualSQL, + $message = '' + ) { + // Normalise SQL queries to remove patterns of repeating whitespace + $expectedSQL = static::normaliseSQL($expectedSQL); + $actualSQL = static::normaliseSQL($actualSQL); + + static::assertEquals($expectedSQL, $actualSQL, $message); + } + + /** + * Asserts that a SQL query contains a SQL fragment + * + * @param string $needleSQL + * @param string $haystackSQL + * @param string $message + */ + public static function assertSQLContains( + $needleSQL, + $haystackSQL, + $message = '' + ) { + $needleSQL = static::normaliseSQL($needleSQL); + $haystackSQL = static::normaliseSQL($haystackSQL); + if (is_iterable($haystackSQL)) { + /** @var iterable $iterableHaystackSQL */ + $iterableHaystackSQL = $haystackSQL; + static::assertContains($needleSQL, $iterableHaystackSQL, $message); + } else { + static::assertStringContainsString($needleSQL, $haystackSQL, $message); + } + } + + /** + * Asserts that a SQL query contains a SQL fragment + * + * @param string $needleSQL + * @param string $haystackSQL + * @param string $message + */ + public static function assertSQLNotContains( + $needleSQL, + $haystackSQL, + $message = '' + ) { + $needleSQL = static::normaliseSQL($needleSQL); + $haystackSQL = static::normaliseSQL($haystackSQL); + if (is_iterable($haystackSQL)) { + /** @var iterable $iterableHaystackSQL */ + $iterableHaystackSQL = $haystackSQL; + static::assertNotContains($needleSQL, $iterableHaystackSQL, $message); + } else { + static::assertStringNotContainsString($needleSQL, $haystackSQL, $message); + } + } + + /** + * Start test environment + */ + public static function start() + { + if (static::is_running_test()) { + return; + } + + // Health check + if (InjectorLoader::inst()->countManifests()) { + throw new LogicException('SapphireTest::start() cannot be called within another application'); + } + static::set_is_running_test(true); + + // Test application + $kernel = new TestKernel(BASE_PATH); + + if (class_exists(HTTPApplication::class)) { + // Mock request + $_SERVER['argv'] = ['vendor/bin/phpunit', '/']; + $request = CLIRequestBuilder::createFromEnvironment(); + + $app = new HTTPApplication($kernel); + $flush = array_key_exists('flush', $request->getVars()); + + // Custom application + $res = $app->execute($request, function (HTTPRequest $request) { + // Start session and execute + $request->getSession()->init($request); + + // Invalidate classname spec since the test manifest will now pull out new subclasses for each internal class + // (e.g. Member will now have various subclasses of DataObjects that implement TestOnly) + DataObject::reset(); + + // Set dummy controller; + $controller = Controller::create(); + $controller->setRequest($request); + $controller->pushCurrent(); + $controller->doInit(); + }, $flush); + + if ($res && $res->isError()) { + throw new LogicException($res->getBody()); + } + } else { + // Allow flush from the command line in the absence of HTTPApplication's special sauce + $flush = false; + foreach ($_SERVER['argv'] as $arg) { + if (preg_match('/^(--)?flush(=1)?$/', $arg)) { + $flush = true; + } + } + $kernel->boot($flush); + } + + // Register state + static::$state = SapphireTestState::singleton(); + // Register temp DB holder + static::tempDB(); + } + + /** + * Reset the testing database's schema, but only if it is active + * @param bool $includeExtraDataObjects If true, the extraDataObjects tables will also be included + * @param bool $forceCreate Force DB to be created if it doesn't exist + */ + public static function resetDBSchema($includeExtraDataObjects = false, $forceCreate = false) + { + if (!static::$tempDB) { + return; + } + + // Check if DB is active before reset + if (!static::$tempDB->isUsed()) { + if (!$forceCreate) { + return; + } + static::$tempDB->build(); + } + $extraDataObjects = $includeExtraDataObjects ? static::getExtraDataObjects() : []; + static::$tempDB->resetDBSchema((array)$extraDataObjects); + } + + /** + * A wrapper for automatically performing callbacks as a user with a specific permission + * + * @param string|array $permCode + * @param callable $callback + * @return mixed + */ + public function actWithPermission($permCode, $callback) + { + return Member::actAs($this->createMemberWithPermission($permCode), $callback); + } + + /** + * Create Member and Group objects on demand with specific permission code + * + * @param string|array $permCode + * @return Member + */ + protected function createMemberWithPermission($permCode) + { + if (is_array($permCode)) { + $permArray = $permCode; + $permCode = implode('.', $permCode); + } else { + $permArray = [$permCode]; + } + + // Check cached member + if (isset($this->cache_generatedMembers[$permCode])) { + $member = $this->cache_generatedMembers[$permCode]; + } else { + // Generate group with these permissions + $group = Group::create(); + $group->Title = "$permCode group"; + $group->write(); + + // Create each individual permission + foreach ($permArray as $permArrayItem) { + $permission = Permission::create(); + $permission->Code = $permArrayItem; + $permission->write(); + $group->Permissions()->add($permission); + } + + $member = Member::get()->filter([ + 'Email' => "$permCode@example.org", + ])->first(); + if (!$member) { + $member = Member::create(); + } + + $member->FirstName = $permCode; + $member->Surname = 'User'; + $member->Email = "$permCode@example.org"; + $member->write(); + $group->Members()->add($member); + + $this->cache_generatedMembers[$permCode] = $member; + } + return $member; + } + + /** + * Create a member and group with the given permission code, and log in with it. + * Returns the member ID. + * + * @param string|array $permCode Either a permission, or list of permissions + * @return int Member ID + */ + public function logInWithPermission($permCode = 'ADMIN') + { + $member = $this->createMemberWithPermission($permCode); + $this->logInAs($member); + return $member->ID; + } + + /** + * Log in as the given member + * + * @param Member|int|string $member The ID, fixture codename, or Member object of the member that you want to log in + */ + public function logInAs($member) + { + if (is_numeric($member)) { + $member = DataObject::get_by_id(Member::class, $member); + } elseif (!is_object($member)) { + $member = $this->objFromFixture(Member::class, $member); + } + Injector::inst()->get(IdentityStore::class)->logIn($member); + } + + /** + * Log out the current user + */ + public function logOut() + { + /** @var IdentityStore $store */ + $store = Injector::inst()->get(IdentityStore::class); + $store->logOut(); + } + + /** + * Cache for logInWithPermission() + */ + protected $cache_generatedMembers = []; + + /** + * Test against a theme. + * + * @param string $themeBaseDir themes directory + * @param string $theme Theme name + * @param callable $callback + * @throws Exception + */ + protected function useTestTheme($themeBaseDir, $theme, $callback) + { + Config::nest(); + if (strpos($themeBaseDir, BASE_PATH) === 0) { + $themeBaseDir = substr($themeBaseDir, strlen(BASE_PATH)); + } + SSViewer::config()->update('theme_enabled', true); + SSViewer::set_themes([$themeBaseDir . '/themes/' . $theme, '$default']); + + try { + $callback(); + } finally { + Config::unnest(); + } + } + + /** + * Get fixture paths for this test + * + * @return array List of paths + */ + protected function getFixturePaths() + { + $fixtureFile = static::get_fixture_file(); + if (empty($fixtureFile)) { + return []; + } + + $fixtureFiles = is_array($fixtureFile) ? $fixtureFile : [$fixtureFile]; + + return array_map(function ($fixtureFilePath) { + return $this->resolveFixturePath($fixtureFilePath); + }, $fixtureFiles); + } + + /** + * Return all extra objects to scaffold for this test + * @return array + */ + public static function getExtraDataObjects() + { + return static::$extra_dataobjects; + } + + /** + * Get additional controller classes to register routes for + * + * @return array + */ + public static function getExtraControllers() + { + return static::$extra_controllers; + } + + /** + * Map a fixture path to a physical file + * + * @param string $fixtureFilePath + * @return string + */ + protected function resolveFixturePath($fixtureFilePath) + { + // support loading via composer name path. + if (strpos($fixtureFilePath, ':') !== false) { + return ModuleResourceLoader::singleton()->resolvePath($fixtureFilePath); + } + + // Support fixture paths relative to the test class, rather than relative to webroot + // String checking is faster than file_exists() calls. + $resolvedPath = realpath($this->getCurrentAbsolutePath() . '/' . $fixtureFilePath); + if ($resolvedPath) { + return $resolvedPath; + } + + // Check if file exists relative to base dir + $resolvedPath = realpath(Director::baseFolder() . '/' . $fixtureFilePath); + if ($resolvedPath) { + return $resolvedPath; + } + + return $fixtureFilePath; + } + + protected function setUpRoutes() + { + if (!class_exists(Director::class)) { + return; + } + + // Get overridden routes + $rules = $this->getExtraRoutes(); + + // Add all other routes + foreach (Director::config()->uninherited('rules') as $route => $rule) { + if (!isset($rules[$route])) { + $rules[$route] = $rule; + } + } + + // Add default catch-all rule + $rules['$Controller//$Action/$ID/$OtherID'] = '*'; + + // Add controller-name auto-routing + Director::config()->set('rules', $rules); + } + + /** + * Get extra routes to merge into Director.rules + * + * @return array + */ + protected function getExtraRoutes() + { + $rules = []; + foreach ($this->getExtraControllers() as $class) { + $controllerInst = Controller::singleton($class); + $link = Director::makeRelative($controllerInst->Link()); + $route = rtrim($link, '/') . '//$Action/$ID/$OtherID'; + $rules[$route] = $class; + } + return $rules; + } + + /** + * Reimplementation of phpunit5 PHPUnit_Util_InvalidArgumentHelper::factory() + * + * @param $argument + * @param $type + * @param $value + */ + public static function createInvalidArgumentException($argument, $type, $value = null) + { + $stack = debug_backtrace(false); + + return new PHPUnitFrameworkException( + sprintf( + 'Argument #%d%sof %s::%s() must be a %s', + $argument, + $value !== null ? ' (' . gettype($value) . '#' . $value . ')' : ' (No Value) ', + $stack[1]['class'], + $stack[1]['function'], + $type + ) + ); + } + + /** + * Returns the annotations for this test. + * + * @return array + */ + public function getAnnotations(): array + { + return TestUtil::parseTestMethodAnnotations( + get_class($this), + $this->getName(false) + ); + } + } +} + +/* ------------------------------------------------- + * + * This version of SapphireTest is for phpunit 5 + * The phpunit 9 verison is at the top of this file + * + * PHPUnit_Extensions_GroupTestSuite is a class that only exists in phpunit 5 + * + * ------------------------------------------------- + */ +if (!class_exists(PHPUnit_Extensions_GroupTestSuite::class)) { return; } @@ -51,8 +1372,12 @@ if (!class_exists(PHPUnit_Framework_TestCase::class)) { * This class should not be used anywhere outside of unit tests, as phpunit may not be installed * in production sites. */ +// Ignore multiple classes in same file +// @codingStandardsIgnoreStart class SapphireTest extends PHPUnit_Framework_TestCase implements TestOnly { + // @codingStandardsIgnoreEnd + /** * Path to fixture data for this test run. * If passed as an array, multiple fixture files will be loaded. @@ -340,7 +1665,6 @@ class SapphireTest extends PHPUnit_Framework_TestCase implements TestOnly } - /** * Helper method to determine if the current test should enable a test database * @@ -439,8 +1763,8 @@ class SapphireTest extends PHPUnit_Framework_TestCase implements TestOnly } /** - * @deprecated 4.0.0:5.0.0 * @return FixtureFactory|false + * @deprecated 4.0.0:5.0.0 */ public function getFixtureFactory() { @@ -452,9 +1776,9 @@ class SapphireTest extends PHPUnit_Framework_TestCase implements TestOnly /** * Sets a new fixture factory - * @deprecated 4.0.0:5.0.0 * @param FixtureFactory $factory * @return $this + * @deprecated 4.0.0:5.0.0 */ public function setFixtureFactory(FixtureFactory $factory) { @@ -533,9 +1857,9 @@ class SapphireTest extends PHPUnit_Framework_TestCase implements TestOnly * Load a YAML fixture file into the database. * Once loaded, you can use idFromFixture() and objFromFixture() to get items from the fixture. * Doesn't clear existing fixtures. + * @param string $fixtureFile The location of the .yml fixture file, relative to the site base dir * @deprecated 4.0.0:5.0.0 * - * @param string $fixtureFile The location of the .yml fixture file, relative to the site base dir */ public function loadFixture($fixtureFile) { @@ -715,7 +2039,6 @@ class SapphireTest extends PHPUnit_Framework_TestCase implements TestOnly ); } - /** * Assert that the given {@link SS_List} includes DataObjects matching the given key-value * pairs. Each match must correspond to 1 distinct record. @@ -756,10 +2079,10 @@ class SapphireTest extends PHPUnit_Framework_TestCase implements TestOnly } /** - * @deprecated 4.0.0:5.0.0 Use assertListContains() instead - * * @param $matches * @param $dataObjectSet + * @deprecated 4.0.0:5.0.0 Use assertListContains() instead + * */ public function assertDOSContains($matches, $dataObjectSet) { @@ -796,7 +2119,7 @@ class SapphireTest extends PHPUnit_Framework_TestCase implements TestOnly ); } - $constraint = new PHPUnit_Framework_Constraint_Not( + $constraint = new PHPUnit_Framework_Constraint_Not( new SSListContains( $matches ) @@ -810,10 +2133,10 @@ class SapphireTest extends PHPUnit_Framework_TestCase implements TestOnly } /** - * @deprecated 4.0.0:5.0.0 Use assertListNotContains() instead - * * @param $matches * @param $dataObjectSet + * @deprecated 4.0.0:5.0.0 Use assertListNotContains() instead + * */ public static function assertNotDOSContains($matches, $dataObjectSet) { @@ -858,10 +2181,10 @@ class SapphireTest extends PHPUnit_Framework_TestCase implements TestOnly } /** - * @deprecated 4.0.0:5.0.0 Use assertListEquals() instead - * * @param $matches * @param SS_List $dataObjectSet + * @deprecated 4.0.0:5.0.0 Use assertListEquals() instead + * */ public function assertDOSEquals($matches, $dataObjectSet) { @@ -869,7 +2192,6 @@ class SapphireTest extends PHPUnit_Framework_TestCase implements TestOnly return static::assertListEquals($matches, $dataObjectSet); } - /** * Assert that the every record in the given {@link SS_List} matches the given key-value * pairs. @@ -902,10 +2224,10 @@ class SapphireTest extends PHPUnit_Framework_TestCase implements TestOnly } /** - * @deprecated 4.0.0:5.0.0 Use assertListAllMatch() instead - * * @param $match * @param SS_List $dataObjectSet + * @deprecated 4.0.0:5.0.0 Use assertListAllMatch() instead + * */ public function assertDOSAllMatch($match, SS_List $dataObjectSet) { diff --git a/tests/behat/src/CmsFormsContext.php b/tests/behat/src/CmsFormsContext.php index 7f495d7e5..f4610ecb2 100644 --- a/tests/behat/src/CmsFormsContext.php +++ b/tests/behat/src/CmsFormsContext.php @@ -7,6 +7,7 @@ use Behat\Behat\Context\Context; use Behat\Mink\Exception\ElementHtmlException; use Behat\Gherkin\Node\TableNode; use Behat\Mink\Session; +use PHPUnit\Framework\Assert; use SilverStripe\BehatExtension\Context\MainContextAwareTrait; use SilverStripe\BehatExtension\Utility\StepHelper; use Symfony\Component\DomCrawler\Crawler; @@ -55,9 +56,9 @@ class CmsFormsContext implements Context $form = $page->find('css', '#Form_EditForm'); if (trim($negative)) { - assertNull($form, 'I should not see an edit page form'); + Assert::assertNull($form, 'I should not see an edit page form'); } else { - assertNotNull($form, 'I should see an edit page form'); + Assert::assertNotNull($form, 'I should see an edit page form'); } } @@ -154,20 +155,31 @@ class CmsFormsContext implements Context $matchedNode = $node; } } - assertNotNull($matchedNode); + Assert::assertNotNull($matchedNode); - $assertFn = $negate ? 'assertNotEquals' : 'assertEquals'; - if($formatting == 'bold') { - call_user_func($assertFn, 'strong', $matchedNode->nodeName); - } else if($formatting == 'left aligned') { - if($matchedNode->getAttribute('class')) { - call_user_func($assertFn, 'text-left', $matchedNode->getAttribute('class')); - } - } else if($formatting == 'right aligned') { - call_user_func($assertFn, 'text-right', $matchedNode->getAttribute('class')); - } - } - // @codingStandardsIgnoreEnd + if ($formatting == 'bold') { + if ($negate) { + Assert::assertNotEquals('strong', $matchedNode->nodeName); + } else { + Assert::assertEquals('strong', $matchedNode->nodeName); + } + } else if ($formatting == 'left aligned') { + if ($matchedNode->getAttribute('class')) { + if ($negate) { + Assert::assertNotEquals('text-left', $matchedNode->getAttribute('class')); + } else { + Assert::assertEquals('text-left', $matchedNode->getAttribute('class')); + } + } + } else if ($formatting == 'right aligned') { + if ($negate) { + Assert::assertNotEquals('text-right', $matchedNode->getAttribute('class')); + } else { + Assert::assertEquals('text-right', $matchedNode->getAttribute('class')); + } + } + } + // @codingStandardsIgnoreEnd /** * Selects the first textual match in the HTML editor. Does not support @@ -226,9 +238,9 @@ JS; } if (trim($negative)) { - assertNull($matchedEl); + Assert::assertNull($matchedEl); } else { - assertNotNull($matchedEl); + Assert::assertNotNull($matchedEl); } } @@ -287,19 +299,19 @@ JS; $parentElement = null; $this->retryThrowable(function () use (&$parentElement, &$page, $selector) { $parentElement = $page->find('css', $selector); - assertNotNull($parentElement, sprintf('"%s" element not found', $selector)); + Assert::assertNotNull($parentElement, sprintf('"%s" element not found', $selector)); $page = $this->getSession()->getPage(); }); $this->retryThrowable(function () use ($parentElement, $selector) { $dropdown = $parentElement->find('css', '.Select-arrow'); - assertNotNull($dropdown, sprintf('Unable to find the dropdown in "%s"', $selector)); + Assert::assertNotNull($dropdown, sprintf('Unable to find the dropdown in "%s"', $selector)); $dropdown->click(); }); $this->retryThrowable(function () use ($text, $parentElement, $selector) { $element = $parentElement->find('xpath', sprintf('//*[count(*)=0 and contains(.,"%s")]', $text)); - assertNotNull($element, sprintf('"%s" not found in "%s"', $text, $selector)); + Assert::assertNotNull($element, sprintf('"%s" not found in "%s"', $text, $selector)); $element->click(); }); } @@ -322,7 +334,7 @@ JS; $element = $this->findInputByLabelContent($locator); } - assertNotNull($element, sprintf('HTML field "%s" not found', $locator)); + Assert::assertNotNull($element, sprintf('HTML field "%s" not found', $locator)); return $element; } @@ -335,7 +347,7 @@ JS; return null; } - assertCount(1, $label, sprintf( + Assert::assertCount(1, $label, sprintf( 'Found more than one element containing the phrase "%s".', $locator )); @@ -406,7 +418,7 @@ JS; public function assertIShouldSeeTheGridFieldButtonForRow($buttonLabel, $gridFieldName, $rowName) { $button = $this->getGridFieldButton($gridFieldName, $rowName, $buttonLabel); - assertNotNull($button, sprintf('Button "%s" not found', $buttonLabel)); + Assert::assertNotNull($button, sprintf('Button "%s" not found', $buttonLabel)); } /** @@ -418,7 +430,7 @@ JS; public function assertIShouldNotSeeTheGridFieldButtonForRow($buttonLabel, $gridFieldName, $rowName) { $button = $this->getGridFieldButton($gridFieldName, $rowName, $buttonLabel); - assertNull($button, sprintf('Button "%s" found', $buttonLabel)); + Assert::assertNull($button, sprintf('Button "%s" found', $buttonLabel)); } /** @@ -430,7 +442,7 @@ JS; public function stepIClickTheGridFieldButtonForRow($buttonLabel, $gridFieldName, $rowName) { $button = $this->getGridFieldButton($gridFieldName, $rowName, $buttonLabel); - assertNotNull($button, sprintf('Button "%s" not found', $buttonLabel)); + Assert::assertNotNull($button, sprintf('Button "%s" not found', $buttonLabel)); $button->click(); } @@ -447,7 +459,7 @@ JS; { $page = $this->getSession()->getPage(); $gridField = $page->find('xpath', sprintf('//*[@data-name="%s"]', $gridFieldName)); - assertNotNull($gridField, sprintf('Gridfield "%s" not found', $gridFieldName)); + Assert::assertNotNull($gridField, sprintf('Gridfield "%s" not found', $gridFieldName)); $name = $gridField->find('xpath', sprintf('//*[count(*)=0 and contains(.,"%s")]', $rowName)); if (!$name) { @@ -472,12 +484,12 @@ JS; { $page = $this->getSession()->getPage(); $listBox = $page->find('xpath', sprintf('//*[@name="%s[]"]', $fieldName)); - assertNotNull($listBox, sprintf('The listbox %s is not found', $fieldName)); + Assert::assertNotNull($listBox, sprintf('The listbox %s is not found', $fieldName)); $option = $listBox->getParent() ->find('css', '.chosen-choices') ->find('xpath', sprintf('//*[count(*)=0 and contains(.,"%s")]', $optionLabel)); - assertNotNull($option, sprintf('Option %s is not found', $optionLabel)); + Assert::assertNotNull($option, sprintf('Option %s is not found', $optionLabel)); $button = $option->getParent()->find('css', 'a'); diff --git a/tests/behat/src/CmsUiContext.php b/tests/behat/src/CmsUiContext.php index 6e5b3f084..b3adb6922 100644 --- a/tests/behat/src/CmsUiContext.php +++ b/tests/behat/src/CmsUiContext.php @@ -8,6 +8,7 @@ use Behat\Mink\Element\Element; use Behat\Mink\Element\NodeElement; use Behat\Mink\Selector\Xpath\Escaper; use Behat\Mink\Session; +use PHPUnit\Framework\Assert; use SilverStripe\BehatExtension\Context\MainContextAwareTrait; use SilverStripe\BehatExtension\Utility\StepHelper; @@ -72,7 +73,7 @@ class CmsUiContext implements Context { $page = $this->getSession()->getPage(); $cms_element = $page->find('css', '.cms'); - assertNotNull($cms_element, 'CMS not found'); + Assert::assertNotNull($cms_element, 'CMS not found'); } /** @@ -116,9 +117,9 @@ class CmsUiContext implements Context { $page = $this->getMainContext()->getSession()->getPage(); $toasts = $page->find('css', '.toasts'); - assertNotNull($toasts, "We have a toast container"); + Assert::assertNotNull($toasts, "We have a toast container"); $toastAction = $toasts->find('named', ['link_or_button', "'{$action}'"]); - assertNotNull($toastAction, "We have a $action toast action"); + Assert::assertNotNull($toastAction, "We have a $action toast action"); $toastAction->click(); } @@ -145,7 +146,7 @@ class CmsUiContext implements Context $page = $this->getSession()->getPage(); $cms_content_header_tabs = $page->find('css', '.cms-content-header-tabs'); - assertNotNull($cms_content_header_tabs, 'CMS tabs not found'); + Assert::assertNotNull($cms_content_header_tabs, 'CMS tabs not found'); return $cms_content_header_tabs; } @@ -160,7 +161,7 @@ class CmsUiContext implements Context $page = $this->getSession()->getPage(); $cms_content_toolbar_element = $page->find('css', '.cms-content-toolbar'); - assertNotNull($cms_content_toolbar_element, 'CMS content toolbar not found'); + Assert::assertNotNull($cms_content_toolbar_element, 'CMS content toolbar not found'); return $cms_content_toolbar_element; } @@ -174,7 +175,7 @@ class CmsUiContext implements Context $page = $this->getSession()->getPage(); $cms_tree_element = $page->find('css', '.cms-tree'); - assertNotNull($cms_tree_element, 'CMS tree not found'); + Assert::assertNotNull($cms_tree_element, 'CMS tree not found'); return $cms_tree_element; } @@ -187,7 +188,7 @@ class CmsUiContext implements Context $cms_content_toolbar_element = $this->getCmsContentToolbarElement(); $element = $cms_content_toolbar_element->find('named', ['link_or_button', "'$text'"]); - assertNotNull($element, sprintf('%s button not found', $text)); + Assert::assertNotNull($element, sprintf('%s button not found', $text)); } /** @@ -198,7 +199,7 @@ class CmsUiContext implements Context // Wait until visible $cmsTreeElement = $this->getCmsTreeElement(); $element = $cmsTreeElement->find('named', ['content', "'$text'"]); - assertNotNull($element, sprintf('%s not found', $text)); + Assert::assertNotNull($element, sprintf('%s not found', $text)); } /** @@ -209,7 +210,7 @@ class CmsUiContext implements Context // Wait until not visible $cmsTreeElement = $this->getCmsTreeElement(); $element = $cmsTreeElement->find('named', ['content', "'$text'"]); - assertNull($element, sprintf('%s found', $text)); + Assert::assertNull($element, sprintf('%s found', $text)); } /** @@ -224,14 +225,14 @@ class CmsUiContext implements Context ); $page = $this->getSession()->getPage(); $cmsListElement = $page->find('css', '.cms-list'); - assertNotNull($cmsListElement, 'CMS list not found'); + Assert::assertNotNull($cmsListElement, 'CMS list not found'); // Check text within this element $element = $cmsListElement->find('named', ['content', "'$text'"]); if (strstr($negate, 'not')) { - assertNull($element, sprintf('Unexpected %s found in cms list', $text)); + Assert::assertNull($element, sprintf('Unexpected %s found in cms list', $text)); } else { - assertNotNull($element, sprintf('Expected %s not found in cms list', $text)); + Assert::assertNotNull($element, sprintf('Expected %s not found in cms list', $text)); } } @@ -241,7 +242,7 @@ class CmsUiContext implements Context public function stepIShouldSeeInCMSContentTabs($text) { // Wait until visible - assertNotNull($this->getCmsTabElement($text), sprintf('%s content tab not found', $text)); + Assert::assertNotNull($this->getCmsTabElement($text), sprintf('%s content tab not found', $text)); } /** @@ -283,7 +284,7 @@ class CmsUiContext implements Context "window.jQuery && window.jQuery('.jstree-apple-context').size() > 0" ); $regionObj = $context->getRegionObj('.jstree-apple-context'); - assertNotNull($regionObj, "Context menu could not be found"); + Assert::assertNotNull($regionObj, "Context menu could not be found"); $linkObj = $regionObj->findLink($link); if (empty($linkObj)) { @@ -304,7 +305,7 @@ class CmsUiContext implements Context { $treeEl = $this->getCmsTreeElement(); $treeNode = $treeEl->findLink($text); - assertNotNull($treeNode, sprintf('%s not found', $text)); + Assert::assertNotNull($treeNode, sprintf('%s not found', $text)); $this->interactWithElement($treeNode, $method); } @@ -314,7 +315,7 @@ class CmsUiContext implements Context public function stepIClickOnElementInTheHeaderTabs($method, $text) { $tabsNode = $this->getCmsTabElement($text); - assertNotNull($tabsNode, sprintf('%s not found', $text)); + Assert::assertNotNull($tabsNode, sprintf('%s not found', $text)); $this->interactWithElement($tabsNode, $method); } @@ -324,8 +325,8 @@ class CmsUiContext implements Context public function theHeaderTabShouldBeActive($text) { $element = $this->getCmsTabElement($text); - assertNotNull($element); - assertTrue($element->hasClass('active')); + Assert::assertNotNull($element); + Assert::assertTrue($element->hasClass('active')); } /** @@ -334,8 +335,8 @@ class CmsUiContext implements Context public function theHeaderTabShouldNotBeActive($text) { $element = $this->getCmsTabElement($text); - assertNotNull($element); - assertFalse($element->hasClass('active')); + Assert::assertNotNull($element); + Assert::assertFalse($element->hasClass('active')); } /** @@ -354,7 +355,7 @@ class CmsUiContext implements Context //Tries to find the first visiable toggle in the page $page = $this->getSession()->getPage(); $toggle_elements = $page->findAll('css', '.toggle-expand'); - assertNotNull($toggle_elements, 'Panel toggle not found'); + Assert::assertNotNull($toggle_elements, 'Panel toggle not found'); /** @var NodeElement $toggle */ foreach ($toggle_elements as $toggle) { if ($toggle->isVisible()) { @@ -370,7 +371,7 @@ class CmsUiContext implements Context { $page = $this->getSession()->getPage(); $filterButton = $page->find('css', '.search-box__filter-trigger'); - assertNotNull($filterButton, sprintf('Filter button link not found')); + Assert::assertNotNull($filterButton, sprintf('Filter button link not found')); $filterButtonExpanded = $filterButton->getAttribute('aria-expanded'); @@ -421,20 +422,20 @@ SCRIPT //Tries to find the first visiable matched Node in the page $treeEl = $this->getCmsTreeElement(); $treeNode = $treeEl->findLink($nodeText); - assertNotNull($treeNode, sprintf('%s link not found', $nodeText)); + Assert::assertNotNull($treeNode, sprintf('%s link not found', $nodeText)); $cssIcon = $treeNode->getParent()->getAttribute("class"); if ($action == "expand") { //ensure it is collapsed if (false === strpos($cssIcon, 'jstree-open')) { $nodeIcon = $treeNode->getParent()->find('css', '.jstree-icon'); - assertTrue($nodeIcon->isVisible(), "CMS node '$nodeText' not found"); + Assert::assertTrue($nodeIcon->isVisible(), "CMS node '$nodeText' not found"); $nodeIcon->click(); } } else { //ensure it is expanded if (false === strpos($cssIcon, 'jstree-closed')) { $nodeIcon = $treeNode->getParent()->find('css', '.jstree-icon'); - assertTrue($nodeIcon->isVisible(), "CMS node '$nodeText' not found"); + Assert::assertTrue($nodeIcon->isVisible(), "CMS node '$nodeText' not found"); $nodeIcon->click(); } } @@ -452,7 +453,7 @@ SCRIPT $page = $this->getSession()->getPage(); $tabsets = $page->findAll('css', '.ui-tabs-nav'); - assertNotNull($tabsets, 'CMS tabs not found'); + Assert::assertNotNull($tabsets, 'CMS tabs not found'); $tab_element = null; /** @var NodeElement $tabset */ @@ -463,9 +464,9 @@ SCRIPT } } if ($negate) { - assertNull($tab_element, sprintf('%s tab found', $tab)); + Assert::assertNull($tab_element, sprintf('%s tab found', $tab)); } else { - assertNotNull($tab_element, sprintf('%s tab not found', $tab)); + Assert::assertNotNull($tab_element, sprintf('%s tab not found', $tab)); } } @@ -481,7 +482,7 @@ SCRIPT $page = $this->getSession()->getPage(); $tabsets = $page->findAll('css', '.ui-tabs-nav'); - assertNotNull($tabsets, 'CMS tabs not found'); + Assert::assertNotNull($tabsets, 'CMS tabs not found'); $tab_element = null; /** @var NodeElement $tabset */ @@ -491,7 +492,7 @@ SCRIPT } $tab_element = $tabset->find('named', ['link_or_button', "'$tab'"]); } - assertNotNull($tab_element, sprintf('%s tab not found', $tab)); + Assert::assertNotNull($tab_element, sprintf('%s tab not found', $tab)); $tab_element->click(); } @@ -544,13 +545,13 @@ SCRIPT public function iSwitchThePreviewToMode($mode) { $controls = $this->getSession()->getPage()->find('css', '.cms-preview-controls'); - assertNotNull($controls, 'Preview controls not found'); + Assert::assertNotNull($controls, 'Preview controls not found'); $label = $controls->find('xpath', sprintf( './/*[count(*)=0 and contains(text(), \'%s\')]', $mode )); - assertNotNull($label, 'Preview mode switch not found'); + Assert::assertNotNull($label, 'Preview mode switch not found'); $label->click(); @@ -654,7 +655,7 @@ SCRIPT } } - assertGreaterThan(0, count($formFields), sprintf( + Assert::assertGreaterThan(0, count($formFields), sprintf( 'Chosen.js dropdown named "%s" not found', $field )); @@ -669,11 +670,11 @@ SCRIPT } } - assertNotNull($container, 'Chosen.js field container not found'); + Assert::assertNotNull($container, 'Chosen.js field container not found'); // Click on newly expanded list element, indirectly setting the dropdown value $linkEl = $container->find('xpath', './/a'); - assertNotNull($linkEl, 'Chosen.js link element not found'); + Assert::assertNotNull($linkEl, 'Chosen.js link element not found'); $this->getSession()->wait(100); // wait for dropdown overlay to appear $linkEl->click(); diff --git a/tests/behat/src/ConfigContext.php b/tests/behat/src/ConfigContext.php index 7da49e94b..0e10db850 100644 --- a/tests/behat/src/ConfigContext.php +++ b/tests/behat/src/ConfigContext.php @@ -5,6 +5,7 @@ namespace SilverStripe\Framework\Tests\Behaviour; use Behat\Behat\Context\Context; use Behat\Behat\Hook\Scope\AfterScenarioScope; use InvalidArgumentException; +use PHPUnit\Framework\Assert; use SilverStripe\BehatExtension\Context\MainContextAwareTrait; use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Kernel; @@ -109,19 +110,19 @@ class ConfigContext implements Context // Ensure site is in dev mode /** @var Kernel $kernel */ $kernel = Injector::inst()->get(Kernel::class); - assertEquals(Kernel::DEV, $kernel->getEnvironment(), "Site is in dev mode"); + Assert::assertEquals(Kernel::DEV, $kernel->getEnvironment(), "Site is in dev mode"); // Ensure file exists in specified fixture dir $sourceDir = $this->getConfigPath(); $sourcePath = "{$sourceDir}/{$filename}"; - assertFileExists($sourcePath, "Config file {$filename} exists"); + Assert::assertFileExists($sourcePath, "Config file {$filename} exists"); // Get destination $project = ModuleManifest::config()->get('project') ?: 'mysite'; $mysite = ModuleLoader::getModule($project); - assertNotNull($mysite, 'Project exists'); + Assert::assertNotNull($mysite, 'Project exists'); $destPath = $mysite->getResource("_config/{$filename}")->getPath(); - assertFileNotExists($destPath, "Config file {$filename} hasn't aleady been loaded"); + Assert::assertFileDoesNotExist($destPath, "Config file {$filename} hasn't aleady been loaded"); // Load $this->activatedConfigFiles[] = $destPath; diff --git a/tests/php/Control/ControllerTest.php b/tests/php/Control/ControllerTest.php index 520f7ce5f..fbdb11ba1 100644 --- a/tests/php/Control/ControllerTest.php +++ b/tests/php/Control/ControllerTest.php @@ -42,7 +42,7 @@ class ControllerTest extends FunctionalTest UnsecuredController::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); Director::config()->update('alternate_base_url', '/'); @@ -60,7 +60,7 @@ class ControllerTest extends FunctionalTest { /* For a controller with a template, the default action will simple run that template. */ $response = $this->get("TestController/"); - $this->assertContains("This is the main template. Content is 'default content'", $response->getBody()); + $this->assertStringContainsString("This is the main template. Content is 'default content'", $response->getBody()); } public function testMethodActions() @@ -68,18 +68,18 @@ class ControllerTest extends FunctionalTest /* The Action can refer to a method that is called on the object. If a method returns an array, then it * will be used to customise the template data */ $response = $this->get("TestController/methodaction"); - $this->assertContains("This is the main template. Content is 'methodaction content'.", $response->getBody()); + $this->assertStringContainsString("This is the main template. Content is 'methodaction content'.", $response->getBody()); /* If the method just returns a string, then that will be used as the response */ $response = $this->get("TestController/stringaction"); - $this->assertContains("stringaction was called.", $response->getBody()); + $this->assertStringContainsString("stringaction was called.", $response->getBody()); } public function testTemplateActions() { /* If there is no method, it can be used to point to an alternative template. */ $response = $this->get("TestController/templateaction"); - $this->assertContains( + $this->assertStringContainsString( "This is the template for templateaction. Content is 'default content'.", $response->getBody() ); @@ -262,12 +262,10 @@ class ControllerTest extends FunctionalTest $this->logOut(); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Invalid allowed_action '*' - */ public function testWildcardAllowedActions() { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage("Invalid allowed_action '*'"); $this->get('AccessWildcardSecuredController'); } diff --git a/tests/php/Control/CookieTest.php b/tests/php/Control/CookieTest.php index d08bb9754..8f2a8eaaa 100644 --- a/tests/php/Control/CookieTest.php +++ b/tests/php/Control/CookieTest.php @@ -10,7 +10,7 @@ use SilverStripe\Control\Cookie; class CookieTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); Injector::inst()->registerService(new CookieJar($_COOKIE), 'SilverStripe\\Control\\Cookie_Backend'); diff --git a/tests/php/Control/DirectorTest.php b/tests/php/Control/DirectorTest.php index 115b24c9a..e6fdc26c8 100644 --- a/tests/php/Control/DirectorTest.php +++ b/tests/php/Control/DirectorTest.php @@ -29,7 +29,7 @@ class DirectorTest extends SapphireTest private $originalEnvType; - protected function setUp() + protected function setUp(): void { parent::setUp(); Director::config()->set('alternate_base_url', 'http://www.mysite.com:9090/'); @@ -44,10 +44,10 @@ class DirectorTest extends SapphireTest $this->expectedRedirect = null; } - protected function tearDown(...$args) + protected function tearDown(): void { Environment::setEnv('SS_ENVIRONMENT_TYPE', $this->originalEnvType); - parent::tearDown(...$args); + parent::tearDown(); } protected function getExtraRoutes() diff --git a/tests/php/Control/Email/EmailTest.php b/tests/php/Control/Email/EmailTest.php index 8857cfed6..3eee3636f 100644 --- a/tests/php/Control/Email/EmailTest.php +++ b/tests/php/Control/Email/EmailTest.php @@ -3,7 +3,7 @@ namespace SilverStripe\Control\Tests\Email; use DateTime; -use PHPUnit_Framework_MockObject_MockObject; +use PHPUnit\Framework\MockObject\MockObject; use SilverStripe\Control\Email\Email; use SilverStripe\Control\Email\Mailer; use SilverStripe\Control\Email\SwiftMailer; @@ -136,7 +136,7 @@ class EmailTest extends SapphireTest public function testSend() { - /** @var Email|PHPUnit_Framework_MockObject_MockObject $email */ + /** @var Email|MockObject $email */ $email = $this->makeEmailMock('Test send HTML'); // email should not call render if a body is supplied @@ -166,7 +166,7 @@ class EmailTest extends SapphireTest public function testRenderedSend() { - /** @var Email|PHPUnit_Framework_MockObject_MockObject $email */ + /** @var Email|MockObject $email */ $email = $this->getMockBuilder(Email::class) ->enableProxyingToOriginalMethods() ->getMock(); @@ -193,7 +193,7 @@ class EmailTest extends SapphireTest '$default', ]); - /** @var Email|PHPUnit_Framework_MockObject_MockObject $email */ + /** @var Email|MockObject $email */ $email = $this->getMockBuilder(EmailSubClass::class) ->enableProxyingToOriginalMethods() ->getMock(); @@ -207,7 +207,7 @@ class EmailTest extends SapphireTest $email->send(); $this->assertTrue($email->hasPlainPart()); $this->assertNotEmpty($email->getBody()); - $this->assertContains('

Email Sub-class

', $email->getBody()); + $this->assertStringContainsString('

Email Sub-class

', $email->getBody()); } public function testConsturctor() @@ -527,7 +527,7 @@ class EmailTest extends SapphireTest public function testGetFailedRecipients() { $mailer = new SwiftMailer(); - /** @var Swift_NullTransport|PHPUnit_Framework_MockObject_MockObject $transport */ + /** @var Swift_NullTransport|MockObject $transport */ $transport = $this->getMockBuilder(Swift_NullTransport::class)->getMock(); $transport->expects($this->once()) ->method('send') @@ -552,7 +552,7 @@ class EmailTest extends SapphireTest 'EmailContent' => 'my content', ]); $email->render(); - $this->assertContains('my content', $email->getBody()); + $this->assertStringContainsString('my content', $email->getBody()); $children = $email->getSwiftMessage()->getChildren(); $this->assertCount(1, $children); $plainPart = reset($children); @@ -570,7 +570,7 @@ class EmailTest extends SapphireTest 'EmailContent' => 'my content', ]); $email->render(); - $this->assertContains('my content', $email->getBody()); + $this->assertStringContainsString('my content', $email->getBody()); $children = $email->getSwiftMessage()->getChildren(); $this->assertCount(1, $children); $plainPart = reset($children); @@ -581,19 +581,19 @@ class EmailTest extends SapphireTest 'EmailContent' => 'your content' ]); $email->render(); - $this->assertContains('your content', $email->getBody()); + $this->assertStringContainsString('your content', $email->getBody()); // Ensure removing data causes a rerender $email->removeData('EmailContent'); $email->render(); - $this->assertNotContains('your content', $email->getBody()); + $this->assertStringNotContainsString('your content', $email->getBody()); // Ensure adding data causes a rerender $email->addData([ 'EmailContent' => 'their content' ]); $email->render(); - $this->assertContains('their content', $email->getBody()); + $this->assertStringContainsString('their content', $email->getBody()); } public function testRenderPlainOnly() @@ -631,8 +631,8 @@ class EmailTest extends SapphireTest $children = $email->getSwiftMessage()->getChildren(); $this->assertCount(1, $children); $plainPart = reset($children); - $this->assertContains('Test', $plainPart->getBody()); - $this->assertNotContains('

Test

', $plainPart->getBody()); + $this->assertStringContainsString('Test', $plainPart->getBody()); + $this->assertStringNotContainsString('

Test

', $plainPart->getBody()); } public function testMultipleEmailSends() @@ -644,30 +644,30 @@ class EmailTest extends SapphireTest $this->assertEmpty($email->getBody()); $this->assertEmpty($email->getSwiftMessage()->getChildren()); $email->send(); - $this->assertContains('Test', $email->getBody()); + $this->assertStringContainsString('Test', $email->getBody()); $this->assertCount(1, $email->getSwiftMessage()->getChildren()); $children = $email->getSwiftMessage()->getChildren(); /** @var \Swift_MimePart $plainPart */ $plainPart = reset($children); - $this->assertContains('Test', $plainPart->getBody()); + $this->assertStringContainsString('Test', $plainPart->getBody()); //send again $email->send(); - $this->assertContains('Test', $email->getBody()); + $this->assertStringContainsString('Test', $email->getBody()); $this->assertCount(1, $email->getSwiftMessage()->getChildren()); $children = $email->getSwiftMessage()->getChildren(); /** @var \Swift_MimePart $plainPart */ $plainPart = reset($children); - $this->assertContains('Test', $plainPart->getBody()); + $this->assertStringContainsString('Test', $plainPart->getBody()); } /** - * @return PHPUnit_Framework_MockObject_MockObject|Email + * @return MockObject|Email */ protected function makeEmailMock($subject) { - /** @var Email|PHPUnit_Framework_MockObject_MockObject $email */ + /** @var Email|MockObject $email */ $email = $this->getMockBuilder(Email::class) ->enableProxyingToOriginalMethods() ->getMock(); diff --git a/tests/php/Control/Email/SwiftPluginTest.php b/tests/php/Control/Email/SwiftPluginTest.php index da809552d..25adb7bbe 100644 --- a/tests/php/Control/Email/SwiftPluginTest.php +++ b/tests/php/Control/Email/SwiftPluginTest.php @@ -9,7 +9,7 @@ use SilverStripe\Dev\SapphireTest; class SwiftPluginTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Control/HTTPCacheControlIntegrationTest.php b/tests/php/Control/HTTPCacheControlIntegrationTest.php index 94b0f1527..ed2c8af8c 100644 --- a/tests/php/Control/HTTPCacheControlIntegrationTest.php +++ b/tests/php/Control/HTTPCacheControlIntegrationTest.php @@ -16,7 +16,7 @@ class HTTPCacheControlIntegrationTest extends FunctionalTest RuleController::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); HTTPCacheControlMiddleware::config() @@ -31,11 +31,11 @@ class HTTPCacheControlIntegrationTest extends FunctionalTest $response = $this->get('HTTPCacheControlIntegrationTest_SessionController/showform'); $header = $response->getHeader('Cache-Control'); $this->assertFalse($response->isError()); - $this->assertNotContains('public', $header); - $this->assertNotContains('private', $header); - $this->assertContains('no-cache', $header); - $this->assertContains('no-store', $header); - $this->assertContains('must-revalidate', $header); + $this->assertStringNotContainsString('public', $header); + $this->assertStringNotContainsString('private', $header); + $this->assertStringContainsString('no-cache', $header); + $this->assertStringContainsString('no-store', $header); + $this->assertStringContainsString('must-revalidate', $header); } public function testPublicForm() @@ -44,10 +44,10 @@ class HTTPCacheControlIntegrationTest extends FunctionalTest $response = $this->get('HTTPCacheControlIntegrationTest_SessionController/showpublicform'); $header = $response->getHeader('Cache-Control'); $this->assertFalse($response->isError()); - $this->assertContains('public', $header); - $this->assertContains('must-revalidate', $header); - $this->assertNotContains('no-cache', $response->getHeader('Cache-Control')); - $this->assertNotContains('no-store', $response->getHeader('Cache-Control')); + $this->assertStringContainsString('public', $header); + $this->assertStringContainsString('must-revalidate', $header); + $this->assertStringNotContainsString('no-cache', $response->getHeader('Cache-Control')); + $this->assertStringNotContainsString('no-store', $response->getHeader('Cache-Control')); } public function testPrivateActionsError() @@ -56,9 +56,9 @@ class HTTPCacheControlIntegrationTest extends FunctionalTest $response = $this->get('HTTPCacheControlIntegrationTest_SessionController/privateaction'); $header = $response->getHeader('Cache-Control'); $this->assertTrue($response->isError()); - $this->assertContains('no-cache', $header); - $this->assertContains('no-store', $header); - $this->assertContains('must-revalidate', $header); + $this->assertStringContainsString('no-cache', $header); + $this->assertStringContainsString('no-store', $header); + $this->assertStringContainsString('must-revalidate', $header); } public function testPrivateActionsAuthenticated() @@ -68,10 +68,10 @@ class HTTPCacheControlIntegrationTest extends FunctionalTest $response = $this->get('HTTPCacheControlIntegrationTest_SessionController/privateaction'); $header = $response->getHeader('Cache-Control'); $this->assertFalse($response->isError()); - $this->assertContains('private', $header); - $this->assertContains('must-revalidate', $header); - $this->assertNotContains('no-cache', $header); - $this->assertNotContains('no-store', $header); + $this->assertStringContainsString('private', $header); + $this->assertStringContainsString('must-revalidate', $header); + $this->assertStringNotContainsString('no-cache', $header); + $this->assertStringNotContainsString('no-store', $header); } public function testPrivateCache() @@ -79,10 +79,10 @@ class HTTPCacheControlIntegrationTest extends FunctionalTest $response = $this->get('HTTPCacheControlIntegrationTest_RuleController/privateaction'); $header = $response->getHeader('Cache-Control'); $this->assertFalse($response->isError()); - $this->assertContains('private', $header); - $this->assertContains('must-revalidate', $header); - $this->assertNotContains('no-cache', $header); - $this->assertNotContains('no-store', $header); + $this->assertStringContainsString('private', $header); + $this->assertStringContainsString('must-revalidate', $header); + $this->assertStringNotContainsString('no-cache', $header); + $this->assertStringNotContainsString('no-store', $header); } public function testPublicCache() @@ -90,11 +90,11 @@ class HTTPCacheControlIntegrationTest extends FunctionalTest $response = $this->get('HTTPCacheControlIntegrationTest_RuleController/publicaction'); $header = $response->getHeader('Cache-Control'); $this->assertFalse($response->isError()); - $this->assertContains('public', $header); - $this->assertContains('must-revalidate', $header); - $this->assertNotContains('no-cache', $header); - $this->assertNotContains('no-store', $header); - $this->assertContains('max-age=9000', $header); + $this->assertStringContainsString('public', $header); + $this->assertStringContainsString('must-revalidate', $header); + $this->assertStringNotContainsString('no-cache', $header); + $this->assertStringNotContainsString('no-store', $header); + $this->assertStringContainsString('max-age=9000', $header); } public function testDisabledCache() @@ -102,10 +102,10 @@ class HTTPCacheControlIntegrationTest extends FunctionalTest $response = $this->get('HTTPCacheControlIntegrationTest_RuleController/disabledaction'); $header = $response->getHeader('Cache-Control'); $this->assertFalse($response->isError()); - $this->assertNotContains('public', $header); - $this->assertNotContains('private', $header); - $this->assertContains('no-cache', $header); - $this->assertContains('no-store', $header); - $this->assertContains('must-revalidate', $header); + $this->assertStringNotContainsString('public', $header); + $this->assertStringNotContainsString('private', $header); + $this->assertStringContainsString('no-cache', $header); + $this->assertStringContainsString('no-store', $header); + $this->assertStringContainsString('must-revalidate', $header); } } diff --git a/tests/php/Control/HTTPRequestTest.php b/tests/php/Control/HTTPRequestTest.php index 52ce61b49..d9778f8a4 100644 --- a/tests/php/Control/HTTPRequestTest.php +++ b/tests/php/Control/HTTPRequestTest.php @@ -52,11 +52,10 @@ class HTTPRequestTest extends SapphireTest /** * This test just asserts a warning is given if there is more than one wildcard parameter. Note that this isn't an * enforcement of an API and we an add new behaviour in the future to allow many wildcard params if we want to - * - * @expectedException \PHPUnit_Framework_Error_Warning */ public function testWildCardWithFurtherParams() { + $this->expectWarning(); $request = new HTTPRequest('GET', 'admin/crm/test'); // all parameters after the first wildcard parameter are ignored $request->match('admin/$Action/$@/$Other/$*', true); diff --git a/tests/php/Control/HTTPTest.php b/tests/php/Control/HTTPTest.php index 018c59ce1..03c37aca4 100644 --- a/tests/php/Control/HTTPTest.php +++ b/tests/php/Control/HTTPTest.php @@ -19,7 +19,7 @@ use SilverStripe\Dev\FunctionalTest; */ class HTTPTest extends FunctionalTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); // Set to disabled at null forcing level @@ -48,9 +48,9 @@ class HTTPTest extends FunctionalTest HTTPCacheControlMiddleware::singleton()->setMaxAge(30); $response = new HTTPResponse($body, 200); $this->addCacheHeaders($response); - $this->assertContains('no-cache', $response->getHeader('Cache-Control')); - $this->assertContains('no-store', $response->getHeader('Cache-Control')); - $this->assertContains('must-revalidate', $response->getHeader('Cache-Control')); + $this->assertStringContainsString('no-cache', $response->getHeader('Cache-Control')); + $this->assertStringContainsString('no-store', $response->getHeader('Cache-Control')); + $this->assertStringContainsString('must-revalidate', $response->getHeader('Cache-Control')); // Ensure max-age setting is respected in production. HTTPCacheControlMiddleware::config() @@ -61,8 +61,8 @@ class HTTPTest extends FunctionalTest HTTPCacheControlMiddleware::singleton()->setMaxAge(30); $response = new HTTPResponse($body, 200); $this->addCacheHeaders($response); - $this->assertContains('max-age=30', $response->getHeader('Cache-Control')); - $this->assertNotContains('max-age=0', $response->getHeader('Cache-Control')); + $this->assertStringContainsString('max-age=30', $response->getHeader('Cache-Control')); + $this->assertStringNotContainsString('max-age=0', $response->getHeader('Cache-Control')); // Still "live": Ensure header's aren't overridden if already set (using purposefully different values). $headers = [ @@ -93,11 +93,11 @@ class HTTPTest extends FunctionalTest // Vary set properly $v = $response->getHeader('Vary'); - $this->assertContains("X-Forwarded-Protocol", $v); - $this->assertContains("X-Requested-With", $v); - $this->assertNotContains("Cookie", $v); - $this->assertNotContains("User-Agent", $v); - $this->assertNotContains("Accept", $v); + $this->assertStringContainsString("X-Forwarded-Protocol", $v); + $this->assertStringContainsString("X-Requested-With", $v); + $this->assertStringNotContainsString("Cookie", $v); + $this->assertStringNotContainsString("User-Agent", $v); + $this->assertStringNotContainsString("Accept", $v); // No vary HTTPCacheControlMiddleware::singleton() @@ -124,7 +124,7 @@ class HTTPTest extends FunctionalTest $response = new HTTPResponse('', 200); $this->addCacheHeaders($response); $header = $response->getHeader('Vary'); - $this->assertContains('X-Foo', $header); + $this->assertStringContainsString('X-Foo', $header); } public function testDeprecatedCacheControlHandling() @@ -143,8 +143,8 @@ class HTTPTest extends FunctionalTest $response = new HTTPResponse('', 200); $this->addCacheHeaders($response); $header = $response->getHeader('Cache-Control'); - $this->assertContains('no-store', $header); - $this->assertContains('no-cache', $header); + $this->assertStringContainsString('no-store', $header); + $this->assertStringContainsString('no-cache', $header); } public function testDeprecatedCacheControlHandlingOnMaxAge() @@ -164,15 +164,13 @@ class HTTPTest extends FunctionalTest $response = new HTTPResponse('', 200); $this->addCacheHeaders($response); $header = $response->getHeader('Cache-Control'); - $this->assertContains('max-age=99', $header); + $this->assertStringContainsString('max-age=99', $header); } - /** - * @expectedException \LogicException - * @expectedExceptionMessageRegExp /Found unsupported legacy directives in HTTP\.cache_control: unknown/ - */ public function testDeprecatedCacheControlHandlingThrowsWithUnknownDirectives() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessageMatches('/Found unsupported legacy directives in HTTP\.cache_control: unknown/'); /** @var Config */ Config::modify()->set( HTTP::class, @@ -219,7 +217,7 @@ class HTTPTest extends FunctionalTest sort($result); sort($expected); - $this->assertInternalType('array', $result); + $this->assertIsArray($result); $this->assertEquals($expected, $result, 'Test that all links within the content are found.'); } @@ -235,7 +233,7 @@ class HTTPTest extends FunctionalTest $controller->setRequest($request); $controller->pushCurrent(); try { - $this->assertContains( + $this->assertStringContainsString( 'relative/url?foo=bar', HTTP::setGetVar('foo', 'bar'), 'Omitting a URL falls back to current URL' @@ -263,7 +261,7 @@ class HTTPTest extends FunctionalTest 'Absolute URL without path and multipe existing query params, overwriting an existing parameter' ); - $this->assertContains( + $this->assertStringContainsString( 'http://test.com/?foo=new', HTTP::setGetVar('foo', 'new', 'http://test.com/?foo=&foo=old'), 'Absolute URL and empty query param' diff --git a/tests/php/Control/IPUtilsTest.php b/tests/php/Control/IPUtilsTest.php index bc82835d1..4c4a20e02 100644 --- a/tests/php/Control/IPUtilsTest.php +++ b/tests/php/Control/IPUtilsTest.php @@ -17,14 +17,14 @@ use SilverStripe\Control\Util\IPUtils; class IPUtilsTest extends SapphireTest { /** - * @dataProvider testIPv4Provider + * @dataProvider iPv4Provider */ public function testIPv4($matches, $remoteAddr, $cidr) { $this->assertSame($matches, IPUtils::checkIP($remoteAddr, $cidr)); } - public function testIPv4Provider() + public function iPv4Provider() { return [ [true, '192.168.1.1', '192.168.1.1'], @@ -43,7 +43,7 @@ class IPUtilsTest extends SapphireTest } /** - * @dataProvider testIPv6Provider + * @dataProvider iPv6Provider */ public function testIPv6($matches, $remoteAddr, $cidr) { @@ -54,7 +54,7 @@ class IPUtilsTest extends SapphireTest $this->assertSame($matches, IPUtils::checkIP($remoteAddr, $cidr)); } - public function testIPv6Provider() + public function iPv6Provider() { return [ [true, '2a01:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65'], @@ -71,11 +71,11 @@ class IPUtilsTest extends SapphireTest } /** - * @expectedException \RuntimeException * @requires extension sockets */ public function testAnIPv6WithOptionDisabledIPv6() { + $this->expectException(\RuntimeException::class); if (defined('AF_INET6')) { $this->markTestSkipped('Only works when PHP is compiled with the option "disable-ipv6".'); } diff --git a/tests/php/Control/Middleware/CanonicalURLMiddlewareTest.php b/tests/php/Control/Middleware/CanonicalURLMiddlewareTest.php index e4e3caa56..f605b0e07 100644 --- a/tests/php/Control/Middleware/CanonicalURLMiddlewareTest.php +++ b/tests/php/Control/Middleware/CanonicalURLMiddlewareTest.php @@ -16,7 +16,7 @@ class CanonicalURLMiddlewareTest extends SapphireTest */ protected $middleware; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -45,7 +45,7 @@ class CanonicalURLMiddlewareTest extends SapphireTest $this->assertNotSame($mockResponse, $result, 'New response is created and returned'); $this->assertEquals(301, $result->getStatusCode(), 'Basic auth responses are redirected'); - $this->assertContains('https://', $result->getHeader('Location'), 'HTTPS is in the redirect location'); + $this->assertStringContainsString('https://', $result->getHeader('Location'), 'HTTPS is in the redirect location'); } public function testMiddlewareDelegateIsReturnedWhenBasicAuthRedirectIsDisabled() diff --git a/tests/php/Control/Middleware/HTTPCacheControlMiddlewareTest.php b/tests/php/Control/Middleware/HTTPCacheControlMiddlewareTest.php index 1a8b3e4b2..bd9adbfc9 100644 --- a/tests/php/Control/Middleware/HTTPCacheControlMiddlewareTest.php +++ b/tests/php/Control/Middleware/HTTPCacheControlMiddlewareTest.php @@ -8,7 +8,7 @@ use SilverStripe\Dev\SapphireTest; class HTTPCacheControlMiddlewareTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); // Set to disabled at null forcing level @@ -39,7 +39,7 @@ class HTTPCacheControlMiddlewareTest extends SapphireTest $response = new HTTPResponse(); $cc->applyToResponse($response); - $this->assertContains('must-revalidate', $response->getHeader('cache-control')); + $this->assertStringContainsString('must-revalidate', $response->getHeader('cache-control')); } /** @@ -62,9 +62,9 @@ class HTTPCacheControlMiddlewareTest extends SapphireTest if ($immutable) { $this->assertEquals($originalResponse->getHeader('cache-control'), $response->getHeader('cache-control')); } else { - $this->assertContains('max-age=300', $response->getHeader('cache-control')); - $this->assertNotContains('no-cache', $response->getHeader('cache-control')); - $this->assertNotContains('no-store', $response->getHeader('cache-control')); + $this->assertStringContainsString('max-age=300', $response->getHeader('cache-control')); + $this->assertStringNotContainsString('no-cache', $response->getHeader('cache-control')); + $this->assertStringNotContainsString('no-store', $response->getHeader('cache-control')); } } @@ -78,9 +78,9 @@ class HTTPCacheControlMiddlewareTest extends SapphireTest $response = new HTTPResponse(); $cc->applyToResponse($response); - $this->assertContains('max-age=300', $response->getHeader('cache-control')); - $this->assertNotContains('no-cache', $response->getHeader('cache-control')); - $this->assertNotContains('no-store', $response->getHeader('cache-control')); + $this->assertStringContainsString('max-age=300', $response->getHeader('cache-control')); + $this->assertStringNotContainsString('no-cache', $response->getHeader('cache-control')); + $this->assertStringNotContainsString('no-store', $response->getHeader('cache-control')); } public function testEnableCacheWithMaxAgeAppliesWhenLevelDoesNot() @@ -94,7 +94,7 @@ class HTTPCacheControlMiddlewareTest extends SapphireTest $response = new HTTPResponse(); $cc->applyToResponse($response); - $this->assertContains('max-age=300', $response->getHeader('cache-control')); + $this->assertStringContainsString('max-age=300', $response->getHeader('cache-control')); } public function testPublicCacheWithMaxAge() @@ -107,10 +107,10 @@ class HTTPCacheControlMiddlewareTest extends SapphireTest $response = new HTTPResponse(); $cc->applyToResponse($response); - $this->assertContains('max-age=300', $response->getHeader('cache-control')); + $this->assertStringContainsString('max-age=300', $response->getHeader('cache-control')); // STATE_PUBLIC doesn't contain no-cache or no-store headers to begin with, // so can't test their removal effectively - $this->assertNotContains('no-cache', $response->getHeader('cache-control')); + $this->assertStringNotContainsString('no-cache', $response->getHeader('cache-control')); } public function testPublicCacheWithMaxAgeAppliesWhenLevelDoesNot() @@ -124,7 +124,7 @@ class HTTPCacheControlMiddlewareTest extends SapphireTest $response = new HTTPResponse(); $cc->applyToResponse($response); - $this->assertContains('max-age=300', $response->getHeader('cache-control')); + $this->assertStringContainsString('max-age=300', $response->getHeader('cache-control')); } /** @@ -150,9 +150,9 @@ class HTTPCacheControlMiddlewareTest extends SapphireTest if ($immutable) { $this->assertEquals($originalResponse->getHeader('cache-control'), $response->getHeader('cache-control')); } else { - $this->assertContains('no-store', $response->getHeader('cache-control')); - $this->assertNotContains('max-age', $response->getHeader('cache-control')); - $this->assertNotContains('s-maxage', $response->getHeader('cache-control')); + $this->assertStringContainsString('no-store', $response->getHeader('cache-control')); + $this->assertStringNotContainsString('max-age', $response->getHeader('cache-control')); + $this->assertStringNotContainsString('s-maxage', $response->getHeader('cache-control')); } } @@ -179,9 +179,9 @@ class HTTPCacheControlMiddlewareTest extends SapphireTest if ($immutable) { $this->assertEquals($originalResponse->getHeader('cache-control'), $response->getHeader('cache-control')); } else { - $this->assertContains('no-cache', $response->getHeader('cache-control')); - $this->assertNotContains('max-age', $response->getHeader('cache-control')); - $this->assertNotContains('s-maxage', $response->getHeader('cache-control')); + $this->assertStringContainsString('no-cache', $response->getHeader('cache-control')); + $this->assertStringNotContainsString('max-age', $response->getHeader('cache-control')); + $this->assertStringNotContainsString('s-maxage', $response->getHeader('cache-control')); } } @@ -206,9 +206,9 @@ class HTTPCacheControlMiddlewareTest extends SapphireTest if ($immutable) { $this->assertEquals($originalResponse->getHeader('cache-control'), $response->getHeader('cache-control')); } else { - $this->assertContains('s-maxage=300', $response->getHeader('cache-control')); - $this->assertNotContains('no-cache', $response->getHeader('cache-control')); - $this->assertNotContains('no-store', $response->getHeader('cache-control')); + $this->assertStringContainsString('s-maxage=300', $response->getHeader('cache-control')); + $this->assertStringNotContainsString('no-cache', $response->getHeader('cache-control')); + $this->assertStringNotContainsString('no-store', $response->getHeader('cache-control')); } } @@ -233,9 +233,9 @@ class HTTPCacheControlMiddlewareTest extends SapphireTest if ($immutable) { $this->assertEquals($originalResponse->getHeader('cache-control'), $response->getHeader('cache-control')); } else { - $this->assertContains('must-revalidate', $response->getHeader('cache-control')); - $this->assertNotContains('max-age', $response->getHeader('cache-control')); - $this->assertNotContains('s-maxage', $response->getHeader('cache-control')); + $this->assertStringContainsString('must-revalidate', $response->getHeader('cache-control')); + $this->assertStringNotContainsString('max-age', $response->getHeader('cache-control')); + $this->assertStringNotContainsString('s-maxage', $response->getHeader('cache-control')); } } diff --git a/tests/php/Control/Middleware/RateLimitMiddlewareTest.php b/tests/php/Control/Middleware/RateLimitMiddlewareTest.php index 23da57239..23bda6331 100644 --- a/tests/php/Control/Middleware/RateLimitMiddlewareTest.php +++ b/tests/php/Control/Middleware/RateLimitMiddlewareTest.php @@ -17,7 +17,7 @@ class RateLimitMiddlewareTest extends FunctionalTest TestController::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); DBDatetime::set_mock_now('2017-09-27 00:00:00'); diff --git a/tests/php/Control/RSS/RSSFeedTest.php b/tests/php/Control/RSS/RSSFeedTest.php index 9e41abca0..45d772ac5 100644 --- a/tests/php/Control/RSS/RSSFeedTest.php +++ b/tests/php/Control/RSS/RSSFeedTest.php @@ -24,17 +24,17 @@ class RSSFeedTest extends SapphireTest $rssFeed = new RSSFeed($list, "http://www.example.com", "Test RSS Feed", "Test RSS Feed Description"); $content = $rssFeed->outputToBrowser(); - $this->assertContains('http://www.example.org/item-a/', $content); - $this->assertContains('http://www.example.com/item-b.html', $content); - $this->assertContains('http://www.example.com/item-c.html', $content); + $this->assertStringContainsString('http://www.example.org/item-a/', $content); + $this->assertStringContainsString('http://www.example.com/item-b.html', $content); + $this->assertStringContainsString('http://www.example.com/item-c.html', $content); - $this->assertContains('ItemA', $content); - $this->assertContains('ItemB', $content); - $this->assertContains('ItemC', $content); + $this->assertStringContainsString('ItemA', $content); + $this->assertStringContainsString('ItemB', $content); + $this->assertStringContainsString('ItemC', $content); - $this->assertContains('ItemA Content', $content); - $this->assertContains('ItemB Content', $content); - $this->assertContains('ItemC Content', $content); + $this->assertStringContainsString('ItemA Content', $content); + $this->assertStringContainsString('ItemB Content', $content); + $this->assertStringContainsString('ItemC Content', $content); // Feed #2 - put Content() into and AltContent() into <description> @@ -48,13 +48,13 @@ class RSSFeedTest extends SapphireTest ); $content = $rssFeed->outputToBrowser(); - $this->assertContains('<title>ItemA Content', $content); - $this->assertContains('ItemB Content', $content); - $this->assertContains('ItemC Content', $content); + $this->assertStringContainsString('ItemA Content', $content); + $this->assertStringContainsString('ItemB Content', $content); + $this->assertStringContainsString('ItemC Content', $content); - $this->assertContains('ItemA AltContent', $content); - $this->assertContains('ItemB AltContent', $content); - $this->assertContains('ItemC AltContent', $content); + $this->assertStringContainsString('ItemA AltContent', $content); + $this->assertStringContainsString('ItemB AltContent', $content); + $this->assertStringContainsString('ItemC AltContent', $content); } public function testLinkEncoding() @@ -62,7 +62,7 @@ class RSSFeedTest extends SapphireTest $list = new ArrayList(); $rssFeed = new RSSFeed($list, "http://www.example.com/?param1=true¶m2=true", "Test RSS Feed"); $content = $rssFeed->outputToBrowser(); - $this->assertContains('http://www.example.com/?param1=true&param2=true', $content); + $this->assertStringContainsString('http://www.example.com/?param1=true&param2=true', $content); } public function testRSSFeedWithShortcode() @@ -73,11 +73,11 @@ class RSSFeedTest extends SapphireTest $rssFeed = new RSSFeed($list, "http://www.example.com", "Test RSS Feed", "Test RSS Feed Description"); $content = $rssFeed->outputToBrowser(); - $this->assertContains('http://www.example.org/item-d.html', $content); + $this->assertStringContainsString('http://www.example.org/item-d.html', $content); - $this->assertContains('ItemD', $content); + $this->assertStringContainsString('ItemD', $content); - $this->assertContains( + $this->assertStringContainsString( 'ItemD Content test shortcode output

]]>
', $content ); @@ -92,14 +92,14 @@ class RSSFeedTest extends SapphireTest $rssFeed->setTemplate('RSSFeedTest'); $content = $rssFeed->outputToBrowser(); - $this->assertContains('Test Custom Template', $content); + $this->assertStringContainsString('Test Custom Template', $content); $rssFeed->setTemplate(null); $content = $rssFeed->outputToBrowser(); - $this->assertNotContains('Test Custom Template', $content); + $this->assertStringNotContainsString('Test Custom Template', $content); } - protected function setUp() + protected function setUp(): void { parent::setUp(); Config::modify()->set(Director::class, 'alternate_base_url', '/'); @@ -116,7 +116,7 @@ class RSSFeedTest extends SapphireTest ); } - protected function tearDown() + protected function tearDown(): void { parent::tearDown(); $_SERVER['HTTP_HOST'] = self::$original_host; diff --git a/tests/php/Control/RequestHandlingTest.php b/tests/php/Control/RequestHandlingTest.php index 8dd90515d..2f417fd9d 100644 --- a/tests/php/Control/RequestHandlingTest.php +++ b/tests/php/Control/RequestHandlingTest.php @@ -357,7 +357,7 @@ class RequestHandlingTest extends FunctionalTest $response = $this->post('ControllerFormWithAllowedActions/Form', $data); $this->assertEquals(403, $response->getStatusCode()); // Note: Looks for a specific 403 thrown by Form->httpSubmission(), not RequestHandler->handleRequest() - $this->assertContains('not allowed on form', $response->getBody()); + $this->assertStringContainsString('not allowed on form', $response->getBody()); } public function testActionHandlingOnField() diff --git a/tests/php/Control/SessionTest.php b/tests/php/Control/SessionTest.php index 79c74d682..a1024e703 100644 --- a/tests/php/Control/SessionTest.php +++ b/tests/php/Control/SessionTest.php @@ -18,10 +18,10 @@ class SessionTest extends SapphireTest */ protected $session = null; - protected function setUp() + protected function setUp(): void { $this->session = new Session([]); - return parent::setUp(); + parent::setUp(); } /** @@ -107,11 +107,11 @@ class SessionTest extends SapphireTest /** * @runInSeparateProcess * @preserveGlobalState disabled - * @expectedException BadMethodCallException - * @expectedExceptionMessage Session has already started */ public function testStartErrorsWhenStartingTwice() { + $this->expectException(\BadMethodCallException::class); + $this->expectExceptionMessage('Session has already started'); $req = new HTTPRequest('GET', '/'); $session = new Session(null); // unstarted session $session->start($req); diff --git a/tests/php/Control/SimpleResourceURLGeneratorTest.php b/tests/php/Control/SimpleResourceURLGeneratorTest.php index bfe1a768f..93d92dd3a 100644 --- a/tests/php/Control/SimpleResourceURLGeneratorTest.php +++ b/tests/php/Control/SimpleResourceURLGeneratorTest.php @@ -11,7 +11,7 @@ use SilverStripe\Dev\SapphireTest; class SimpleResourceURLGeneratorTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); Director::config()->set( diff --git a/tests/php/Core/Cache/CacheTest.php b/tests/php/Core/Cache/CacheTest.php index d034ed977..1853acf88 100644 --- a/tests/php/Core/Cache/CacheTest.php +++ b/tests/php/Core/Cache/CacheTest.php @@ -13,7 +13,7 @@ use Symfony\Component\Cache\Simple\MemcachedCache; class CacheTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Core/Cache/RateLimiterTest.php b/tests/php/Core/Cache/RateLimiterTest.php index ec2a80527..011020067 100644 --- a/tests/php/Core/Cache/RateLimiterTest.php +++ b/tests/php/Core/Cache/RateLimiterTest.php @@ -11,7 +11,7 @@ use Symfony\Component\Cache\Simple\ArrayCache; class RateLimiterTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); DBDatetime::set_mock_now('2017-09-27 00:00:00'); diff --git a/tests/php/Core/ClassInfoTest.php b/tests/php/Core/ClassInfoTest.php index 29721599b..840e65889 100644 --- a/tests/php/Core/ClassInfoTest.php +++ b/tests/php/Core/ClassInfoTest.php @@ -3,6 +3,7 @@ namespace SilverStripe\Core\Tests; use DateTime; +use Exception; use ReflectionException; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Tests\ClassInfoTest\BaseClass; @@ -42,7 +43,7 @@ class ClassInfoTest extends SapphireTest ExtendTest3::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); ClassInfo::reset_db_cache(); @@ -106,8 +107,8 @@ class ClassInfoTest extends SapphireTest public function testNonClassName() { - $this->expectException(ReflectionException::class); - $this->expectExceptionMessageRegExp('/Class "?IAmAClassThatDoesNotExist"? does not exist/'); + $this->expectException(Exception::class); + $this->expectExceptionMessageMatches('/Class "?IAmAClassThatDoesNotExist"? does not exist/'); $this->assertEquals('IAmAClassThatDoesNotExist', ClassInfo::class_name('IAmAClassThatDoesNotExist')); } diff --git a/tests/php/Core/ConvertTest.php b/tests/php/Core/ConvertTest.php index b3dec037a..76aec076f 100644 --- a/tests/php/Core/ConvertTest.php +++ b/tests/php/Core/ConvertTest.php @@ -19,14 +19,14 @@ class ConvertTest extends SapphireTest private $previousLocaleSetting = null; - public function setUp() + protected function setUp(): void { parent::setUp(); // clear the previous locale setting $this->previousLocaleSetting = null; } - public function tearDown() + protected function tearDown(): void { parent::tearDown(); // If a test sets the locale, reset it on teardown @@ -242,7 +242,7 @@ PHP $this->assertEquals(3, count($decoded), '3 items in the decoded array'); $this->assertContains('Bloggs', $decoded, 'Contains "Bloggs" value in decoded array'); $this->assertContains('Jones', $decoded, 'Contains "Jones" value in decoded array'); - $this->assertContains('Structure', $decoded['My']['Complicated']); + $this->assertStringContainsString('Structure', $decoded['My']['Complicated']); } /** diff --git a/tests/php/Core/CoreTest.php b/tests/php/Core/CoreTest.php index 9e82804f5..f2a546e55 100644 --- a/tests/php/Core/CoreTest.php +++ b/tests/php/Core/CoreTest.php @@ -15,7 +15,7 @@ class CoreTest extends SapphireTest protected $tempPath; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->tempPath = Director::baseFolder() . DIRECTORY_SEPARATOR . 'silverstripe-cache'; @@ -51,7 +51,7 @@ class CoreTest extends SapphireTest } } - protected function tearDown() + protected function tearDown(): void { parent::tearDown(); $user = TempFolder::getTempFolderUsername(); diff --git a/tests/php/Core/Injector/InjectorTest.php b/tests/php/Core/Injector/InjectorTest.php index ac04d988e..ee3a103bb 100644 --- a/tests/php/Core/Injector/InjectorTest.php +++ b/tests/php/Core/Injector/InjectorTest.php @@ -2,7 +2,6 @@ namespace SilverStripe\Core\Tests\Injector; -use InvalidArgumentException; use SilverStripe\Core\Config\Config; use SilverStripe\Core\Injector\Factory; use SilverStripe\Core\Injector\Injector; @@ -44,14 +43,14 @@ class InjectorTest extends SapphireTest protected $nestingLevel = 0; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->nestingLevel = 0; } - protected function tearDown() + protected function tearDown(): void { while ($this->nestingLevel > 0) { @@ -910,11 +909,9 @@ class InjectorTest extends SapphireTest ); } - /** - * @expectedException InvalidArgumentException - */ public function testNonExistentMethods() { + $this->expectException(\InvalidArgumentException::class); $injector = new Injector(); $config = [ 'TestService' => [ @@ -929,11 +926,9 @@ class InjectorTest extends SapphireTest $item = $injector->get('TestService'); } - /** - * @expectedException InvalidArgumentException - */ public function testProtectedMethods() { + $this->expectException(\InvalidArgumentException::class); $injector = new Injector(); $config = [ 'TestService' => [ @@ -948,11 +943,9 @@ class InjectorTest extends SapphireTest $item = $injector->get('TestService'); } - /** - * @expectedException InvalidArgumentException - */ public function testTooManyArrayValues() { + $this->expectException(\InvalidArgumentException::class); $injector = new Injector(); $config = [ 'TestService' => [ @@ -967,11 +960,9 @@ class InjectorTest extends SapphireTest $item = $injector->get('TestService'); } - /** - * @expectedException \SilverStripe\Core\Injector\InjectorNotFoundException - */ public function testGetThrowsOnNotFound() { + $this->expectException(InjectorNotFoundException::class); $injector = new Injector(); $injector->get('UnknownService'); } diff --git a/tests/php/Core/Manifest/ClassLoaderTest.php b/tests/php/Core/Manifest/ClassLoaderTest.php index 1525fdc3b..d0e3d9f85 100644 --- a/tests/php/Core/Manifest/ClassLoaderTest.php +++ b/tests/php/Core/Manifest/ClassLoaderTest.php @@ -32,7 +32,7 @@ class ClassLoaderTest extends SapphireTest */ protected $testManifest2; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Core/Manifest/ClassManifestErrorHandlerTest.php b/tests/php/Core/Manifest/ClassManifestErrorHandlerTest.php index 0a9ec22a5..075c35d93 100644 --- a/tests/php/Core/Manifest/ClassManifestErrorHandlerTest.php +++ b/tests/php/Core/Manifest/ClassManifestErrorHandlerTest.php @@ -7,12 +7,10 @@ use PhpParser\Error; class ClassManifestErrorHandlerTest extends SapphireTest { - /** - * @expectedException \PhpParser\Error - * @expectedExceptionMessage my error in /my/path - */ public function testIncludesPathname() { + $this->expectException(Error::class); + $this->expectExceptionMessage('my error in /my/path'); $h = new ClassManifestErrorHandler('/my/path'); $e = new Error('my error'); $h->handleError($e); diff --git a/tests/php/Core/Manifest/ClassManifestTest.php b/tests/php/Core/Manifest/ClassManifestTest.php index 40955062f..736f76732 100644 --- a/tests/php/Core/Manifest/ClassManifestTest.php +++ b/tests/php/Core/Manifest/ClassManifestTest.php @@ -27,7 +27,7 @@ class ClassManifestTest extends SapphireTest */ protected $manifestTests; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Core/Manifest/ConfigManifestTest.php b/tests/php/Core/Manifest/ConfigManifestTest.php index fd2c55207..1aaa76f14 100644 --- a/tests/php/Core/Manifest/ConfigManifestTest.php +++ b/tests/php/Core/Manifest/ConfigManifestTest.php @@ -13,7 +13,7 @@ use SilverStripe\Dev\SapphireTest; class ConfigManifestTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -22,7 +22,7 @@ class ConfigManifestTest extends SapphireTest ModuleLoader::inst()->pushManifest($moduleManifest); } - protected function tearDown() + protected function tearDown(): void { ModuleLoader::inst()->popManifest(); parent::tearDown(); @@ -225,7 +225,7 @@ class ConfigManifestTest extends SapphireTest 'Fragment is included if both blocks succeed.' ); } - + public function testExtensionLoaded() { $config = $this->getConfigFixtureValue('ExtensionLoaded'); diff --git a/tests/php/Core/Manifest/ManifestFileFinderTest.php b/tests/php/Core/Manifest/ManifestFileFinderTest.php index 1eb87bf3b..7c0909b10 100644 --- a/tests/php/Core/Manifest/ManifestFileFinderTest.php +++ b/tests/php/Core/Manifest/ManifestFileFinderTest.php @@ -26,7 +26,7 @@ class ManifestFileFinderTest extends SapphireTest * @param array $expect * @param string $message */ - public function assertFinderFinds(ManifestFileFinder $finder, $base, $expect, $message = null) + public function assertFinderFinds(ManifestFileFinder $finder, $base, $expect, $message = '') { if (!$base) { $base = $this->defaultBase; diff --git a/tests/php/Core/Manifest/ModuleManifestTest.php b/tests/php/Core/Manifest/ModuleManifestTest.php index e77adbf99..0106aa5c4 100644 --- a/tests/php/Core/Manifest/ModuleManifestTest.php +++ b/tests/php/Core/Manifest/ModuleManifestTest.php @@ -18,7 +18,7 @@ class ModuleManifestTest extends SapphireTest */ protected $manifest; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Core/Manifest/ModuleResourceTest.php b/tests/php/Core/Manifest/ModuleResourceTest.php index d0d629fe8..c733b636c 100644 --- a/tests/php/Core/Manifest/ModuleResourceTest.php +++ b/tests/php/Core/Manifest/ModuleResourceTest.php @@ -18,7 +18,7 @@ class ModuleResourceTest extends SapphireTest */ protected $manifest; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Core/Manifest/NamespacedClassManifestTest.php b/tests/php/Core/Manifest/NamespacedClassManifestTest.php index fa80e9c63..4db5e3f63 100644 --- a/tests/php/Core/Manifest/NamespacedClassManifestTest.php +++ b/tests/php/Core/Manifest/NamespacedClassManifestTest.php @@ -8,6 +8,7 @@ use SilverStripe\Core\Manifest\ClassManifest; use SilverStripe\Core\Manifest\ClassLoader; use SilverStripe\Dev\SapphireTest; use ReflectionMethod; +use SilverStripe\ORM\DataQuery; use SilverStripe\Security\PermissionProvider; /** @@ -25,7 +26,7 @@ class NamespacedClassManifestTest extends SapphireTest */ protected $manifest; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -35,7 +36,7 @@ class NamespacedClassManifestTest extends SapphireTest ClassLoader::inst()->pushManifest($this->manifest, false); } - protected function tearDown() + protected function tearDown(): void { parent::tearDown(); ClassLoader::inst()->popManifest(); @@ -43,8 +44,9 @@ class NamespacedClassManifestTest extends SapphireTest public function testClassInfoIsCorrect() { + $class = 'SilverStripe\\Framework\\Tests\\ClassI'; $this->assertContains( - 'SilverStripe\\Framework\\Tests\\ClassI', + $class, ClassInfo::implementorsOf(PermissionProvider::class) ); @@ -53,8 +55,13 @@ class NamespacedClassManifestTest extends SapphireTest // including all core classes $method = new ReflectionMethod($this->manifest, 'coalesceDescendants'); $method->setAccessible(true); - $method->invoke($this->manifest, ModelAdmin::class); - $this->assertContains('SilverStripe\\Framework\\Tests\\ClassI', ClassInfo::subclassesFor(ModelAdmin::class)); + $method->invoke($this->manifest, DataQuery::class); + $classes = ClassInfo::subclassesFor(DataQuery::class); + $this->assertContains( + $class, + $classes, + $class . ' not contained in [' . implode(',', $classes) . ']' + ); } public function testGetItemPath() diff --git a/tests/php/Core/Manifest/PrioritySorterTest.php b/tests/php/Core/Manifest/PrioritySorterTest.php index 8c1f2c345..8166fd3b8 100644 --- a/tests/php/Core/Manifest/PrioritySorterTest.php +++ b/tests/php/Core/Manifest/PrioritySorterTest.php @@ -12,7 +12,7 @@ class PrioritySorterTest extends SapphireTest */ protected $sorter; - public function setUp() + protected function setUp(): void { parent::setUp(); $modules = [ diff --git a/tests/php/Core/Manifest/ThemeResourceLoaderTest.php b/tests/php/Core/Manifest/ThemeResourceLoaderTest.php index 043bdd5c3..206cd3fd8 100644 --- a/tests/php/Core/Manifest/ThemeResourceLoaderTest.php +++ b/tests/php/Core/Manifest/ThemeResourceLoaderTest.php @@ -33,7 +33,7 @@ class ThemeResourceLoaderTest extends SapphireTest /** * Set up manifest before each test */ - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -60,7 +60,7 @@ class ThemeResourceLoaderTest extends SapphireTest ThemeResourceLoader::flush(); } - protected function tearDown() + protected function tearDown(): void { ModuleLoader::inst()->popManifest(); parent::tearDown(); diff --git a/tests/php/Core/Manifest/VersionProviderTest.php b/tests/php/Core/Manifest/VersionProviderTest.php index 5d230e0dc..be4319a3e 100644 --- a/tests/php/Core/Manifest/VersionProviderTest.php +++ b/tests/php/Core/Manifest/VersionProviderTest.php @@ -81,9 +81,9 @@ class VersionProviderTest extends SapphireTest 'silverstripe/framework' => 'Framework' ]); $result = $this->getMockProvider()->getVersion(); - $this->assertNotContains('SiteConfig: ', $result); - $this->assertContains('Framework: ', $result); - $this->assertNotContains(', ', $result); + $this->assertStringNotContainsString('SiteConfig: ', $result); + $this->assertStringContainsString('Framework: ', $result); + $this->assertStringNotContainsString(', ', $result); } public function testGetVersionNoRecipe() @@ -93,7 +93,7 @@ class VersionProviderTest extends SapphireTest Config::modify()->set(VersionProvider::class, 'modules', []); $result = $provider->getVersion(); - $this->assertContains('Framework: 1.2.3', $result); + $this->assertStringContainsString('Framework: 1.2.3', $result); Config::modify()->set(VersionProvider::class, 'modules', [ 'silverstripe/framework' => 'Framework', @@ -102,10 +102,10 @@ class VersionProviderTest extends SapphireTest 'silverstripe/recipe-cms' => 'CMS Recipe', ]); $result = $provider->getVersion(); - $this->assertNotContains('Framework: 1.2.3', $result); - $this->assertContains('CMS: 4.5.6', $result); - $this->assertNotContains('Core Recipe: 7.7.7', $result); - $this->assertNotContains('CMS Recipe: 8.8.8', $result); + $this->assertStringNotContainsString('Framework: 1.2.3', $result); + $this->assertStringContainsString('CMS: 4.5.6', $result); + $this->assertStringNotContainsString('Core Recipe: 7.7.7', $result); + $this->assertStringNotContainsString('CMS Recipe: 8.8.8', $result); } public function testGetVersionRecipeCore() @@ -119,10 +119,10 @@ class VersionProviderTest extends SapphireTest 'silverstripe/recipe-cms' => 'CMS Recipe', ]); $result = $provider->getVersion(); - $this->assertNotContains('Framework: 1.2.3', $result); - $this->assertNotContains('Core Recipe: 7.7.7', $result); - $this->assertContains('CMS: 4.5.6', $result); - $this->assertNotContains('CMS Recipe: 8.8.8', $result); + $this->assertStringNotContainsString('Framework: 1.2.3', $result); + $this->assertStringNotContainsString('Core Recipe: 7.7.7', $result); + $this->assertStringContainsString('CMS: 4.5.6', $result); + $this->assertStringNotContainsString('CMS Recipe: 8.8.8', $result); } public function testGetVersionRecipeCmsCore() @@ -139,11 +139,11 @@ class VersionProviderTest extends SapphireTest ]); $result = $provider->getVersion(); - $this->assertNotContains('Framework: 1.2.3', $result); - $this->assertNotContains('CMS: 4.5.6', $result); - $this->assertNotContains('Core Recipe: 7.7.7', $result); - $this->assertContains('CMS Recipe: 8.8.8', $result); - $this->assertNotContains('CWP: 9.9.9', $result); + $this->assertStringNotContainsString('Framework: 1.2.3', $result); + $this->assertStringNotContainsString('CMS: 4.5.6', $result); + $this->assertStringNotContainsString('Core Recipe: 7.7.7', $result); + $this->assertStringContainsString('CMS Recipe: 8.8.8', $result); + $this->assertStringNotContainsString('CWP: 9.9.9', $result); Config::modify()->set(VersionProvider::class, 'modules', [ 'silverstripe/framework' => 'Framework', @@ -153,11 +153,11 @@ class VersionProviderTest extends SapphireTest 'cwp/cwp-core' => 'CWP', ]); $result = $provider->getVersion(); - $this->assertNotContains('Framework: 1.2.3', $result); - $this->assertNotContains('CMS: 4.5.6', $result); - $this->assertNotContains('Core Recipe: 7.7.7', $result); - $this->assertContains('CMS Recipe:', $result); - $this->assertContains('CWP: 9.9.9', $result); + $this->assertStringNotContainsString('Framework: 1.2.3', $result); + $this->assertStringNotContainsString('CMS: 4.5.6', $result); + $this->assertStringNotContainsString('Core Recipe: 7.7.7', $result); + $this->assertStringContainsString('CMS Recipe:', $result); + $this->assertStringContainsString('CWP: 9.9.9', $result); } public function testGetModulesFromComposerLock() @@ -186,6 +186,6 @@ class VersionProviderTest extends SapphireTest ]); $result = $mock->getVersion(); - $this->assertContains('Some Package: 1.2.3', $result); + $this->assertStringContainsString('Some Package: 1.2.3', $result); } } diff --git a/tests/php/Core/Manifest/fixtures/namespaced_classmanifest/module/classes/ClassI.php b/tests/php/Core/Manifest/fixtures/namespaced_classmanifest/module/classes/ClassI.php index 5ffe2948c..209e13ef3 100644 --- a/tests/php/Core/Manifest/fixtures/namespaced_classmanifest/module/classes/ClassI.php +++ b/tests/php/Core/Manifest/fixtures/namespaced_classmanifest/module/classes/ClassI.php @@ -4,7 +4,7 @@ namespace SilverStripe\Framework\Tests; //whitespace here is important for tests, please don't change it /** @skipUpgrade */ -use SilverStripe\Admin\ModelAdmin; +use SilverStripe\ORM\DataQuery; /** @skipUpgrade */ use SilverStripe\Control\Controller as Cont ; /** @skipUpgrade */ @@ -15,5 +15,5 @@ use silverstripe\test\ClassA; use \SilverStripe\Core\ClassInfo; /** @skipUpgrade */ -class ClassI extends ModelAdmin implements P { +class ClassI extends DataQuery implements P { } diff --git a/tests/php/Core/MemoryLimitTest.php b/tests/php/Core/MemoryLimitTest.php index 842e77645..7fda32dee 100644 --- a/tests/php/Core/MemoryLimitTest.php +++ b/tests/php/Core/MemoryLimitTest.php @@ -12,7 +12,7 @@ class MemoryLimitTest extends SapphireTest protected $origMemLimit; protected $origTimeLimit; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -29,7 +29,7 @@ class MemoryLimitTest extends SapphireTest } } - protected function tearDown() + protected function tearDown(): void { if (!in_array('suhosin', get_loaded_extensions())) { ini_set('memory_limit', $this->origMemLimit); @@ -42,23 +42,26 @@ class MemoryLimitTest extends SapphireTest public function testIncreaseMemoryLimitTo() { - ini_set('memory_limit', '64M'); + // ini_set('memory_limit', '64M'); + // current memory usage in travis is 197M, can't ini_set this down to 64M + // Using a higher memory limit instead + ini_set('memory_limit', '230M'); Environment::setMemoryLimitMax('256M'); // It can go up - Environment::increaseMemoryLimitTo('128M'); - $this->assertEquals('128M', ini_get('memory_limit')); + Environment::increaseMemoryLimitTo('240M'); + $this->assertEquals('240M', ini_get('memory_limit')); // But not down - Environment::increaseMemoryLimitTo('64M'); - $this->assertEquals('128M', ini_get('memory_limit')); + Environment::increaseMemoryLimitTo('220M'); + $this->assertEquals('240M', ini_get('memory_limit')); // Test the different kinds of syntaxes - Environment::increaseMemoryLimitTo(1024*1024*200); - $this->assertEquals('200M', ini_get('memory_limit')); + Environment::increaseMemoryLimitTo(1024*1024*250); + $this->assertEquals('250M', ini_get('memory_limit')); Environment::increaseMemoryLimitTo('109600K'); - $this->assertEquals('200M', ini_get('memory_limit')); + $this->assertEquals('250M', ini_get('memory_limit')); // Attempting to increase past max size only sets to max Environment::increaseMemoryLimitTo('1G'); diff --git a/tests/php/Core/ObjectTest.php b/tests/php/Core/ObjectTest.php index ab4ceae4f..cba0b1197 100644 --- a/tests/php/Core/ObjectTest.php +++ b/tests/php/Core/ObjectTest.php @@ -31,7 +31,7 @@ use SilverStripe\Versioned\Versioned; class ObjectTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); Injector::inst()->unregisterObjects([ diff --git a/tests/php/Core/PathTest.php b/tests/php/Core/PathTest.php index 3808b7f91..c6ed6af97 100644 --- a/tests/php/Core/PathTest.php +++ b/tests/php/Core/PathTest.php @@ -68,7 +68,7 @@ class PathTest extends SapphireTest */ public function testJoinPathsErrors($args, $error) { - $this->expectException(InvalidArgumentException::class); + $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage($error); Path::join($args); } diff --git a/tests/php/Core/PhpSyntaxTest.php b/tests/php/Core/PhpSyntaxTest.php index 465b2d5ae..10d51fd3f 100644 --- a/tests/php/Core/PhpSyntaxTest.php +++ b/tests/php/Core/PhpSyntaxTest.php @@ -9,7 +9,7 @@ use SilverStripe\Dev\SapphireTest; */ class PhpSyntaxTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->markTestSkipped('This needs to be written to include only core php files, not test/thirdparty files'); diff --git a/tests/php/Dev/BulkLoaderResultTest.php b/tests/php/Dev/BulkLoaderResultTest.php index be0aa2f8a..c619eed72 100644 --- a/tests/php/Dev/BulkLoaderResultTest.php +++ b/tests/php/Dev/BulkLoaderResultTest.php @@ -13,7 +13,7 @@ class BulkLoaderResultTest extends SapphireTest Player::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); Player::create(['Name' => 'Vincent', 'Status' => 'Available'])->write(); diff --git a/tests/php/Dev/CLIDebugViewTest.php b/tests/php/Dev/CLIDebugViewTest.php index 7d8d06661..20241dcaf 100644 --- a/tests/php/Dev/CLIDebugViewTest.php +++ b/tests/php/Dev/CLIDebugViewTest.php @@ -10,7 +10,7 @@ class CLIDebugViewTest extends SapphireTest { protected $caller = null; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Dev/CSVParserTest.php b/tests/php/Dev/CSVParserTest.php index 0b2a72687..4b2cb62a3 100644 --- a/tests/php/Dev/CSVParserTest.php +++ b/tests/php/Dev/CSVParserTest.php @@ -15,7 +15,7 @@ class CSVParserTest extends SapphireTest */ protected $csvPath = null; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->csvPath = __DIR__ . '/CsvBulkLoaderTest/csv/'; diff --git a/tests/php/Dev/CsvBulkLoaderTest.php b/tests/php/Dev/CsvBulkLoaderTest.php index c7740fd22..89b073755 100644 --- a/tests/php/Dev/CsvBulkLoaderTest.php +++ b/tests/php/Dev/CsvBulkLoaderTest.php @@ -31,7 +31,7 @@ class CsvBulkLoaderTest extends SapphireTest */ protected $csvPath = null; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->csvPath = __DIR__ . '/CsvBulkLoaderTest/csv/'; diff --git a/tests/php/Dev/DebugViewTest.php b/tests/php/Dev/DebugViewTest.php index edafe8bff..b0158646a 100644 --- a/tests/php/Dev/DebugViewTest.php +++ b/tests/php/Dev/DebugViewTest.php @@ -10,7 +10,7 @@ class DebugViewTest extends SapphireTest { protected $caller = null; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Dev/DeprecationTest.php b/tests/php/Dev/DeprecationTest.php index 194d08daf..32bd64f61 100644 --- a/tests/php/Dev/DeprecationTest.php +++ b/tests/php/Dev/DeprecationTest.php @@ -2,7 +2,6 @@ namespace SilverStripe\Dev\Tests; -use PHPUnit_Framework_Error; use SilverStripe\Dev\Deprecation; use SilverStripe\Dev\SapphireTest; use SilverStripe\Dev\Tests\DeprecationTest\TestDeprecation; @@ -12,7 +11,7 @@ class DeprecationTest extends SapphireTest static $originalVersionInfo; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -21,7 +20,7 @@ class DeprecationTest extends SapphireTest Deprecation::set_enabled(true); } - protected function tearDown() + protected function tearDown(): void { Deprecation::restore_settings(self::$originalVersionInfo); parent::tearDown(); @@ -33,11 +32,9 @@ class DeprecationTest extends SapphireTest $this->assertNull(Deprecation::notice('2.0', 'Deprecation test failed')); } - /** - * @expectedException PHPUnit_Framework_Error - */ public function testEqualVersionTriggersNotice() { + $this->expectError(); Deprecation::notification_version('2.0.0'); Deprecation::notice('2.0.0', 'Deprecation test passed'); } @@ -49,11 +46,9 @@ class DeprecationTest extends SapphireTest $this->assertNull(Deprecation::notice('2.0.0', 'Deprecation test failed')); } - /** - * @expectedException PHPUnit_Framework_Error - */ public function testGreaterVersionTriggersNotice() { + $this->expectError(); Deprecation::notification_version('3.0.0'); Deprecation::notice('2.0', 'Deprecation test passed'); } @@ -65,11 +60,9 @@ class DeprecationTest extends SapphireTest $this->callThatOriginatesFromFramework(); } - /** - * @expectedException PHPUnit_Framework_Error - */ public function testMatchingModuleNotifcationVersionAffectsNotice() { + $this->expectError(); Deprecation::notification_version('1.0.0'); Deprecation::notification_version('3.0.0', 'silverstripe/framework'); $this->callThatOriginatesFromFramework(); @@ -83,32 +76,26 @@ class DeprecationTest extends SapphireTest ); } - /** - * @expectedException PHPUnit_Framework_Error - * @expectedExceptionMessage DeprecationTest->testScopeMethod is deprecated. Method scope - */ public function testScopeMethod() { + $this->expectError(); + $this->expectErrorMessage('DeprecationTest->testScopeMethod is deprecated. Method scope'); Deprecation::notification_version('2.0.0'); Deprecation::notice('2.0.0', 'Method scope', Deprecation::SCOPE_METHOD); } - /** - * @expectedException PHPUnit_Framework_Error - * @expectedExceptionMessage DeprecationTest is deprecated. Class scope - */ public function testScopeClass() { + $this->expectError(); + $this->expectErrorMessage('DeprecationTest is deprecated. Class scope'); Deprecation::notification_version('2.0.0'); Deprecation::notice('2.0.0', 'Class scope', Deprecation::SCOPE_CLASS); } - /** - * @expectedException PHPUnit_Framework_Error - * @expectedExceptionMessage Global scope - */ public function testScopeGlobal() { + $this->expectError(); + $this->expectErrorMessage('Global scope'); Deprecation::notification_version('2.0.0'); Deprecation::notice('2.0.0', 'Global scope', Deprecation::SCOPE_GLOBAL); } diff --git a/tests/php/Dev/DevAdminControllerTest.php b/tests/php/Dev/DevAdminControllerTest.php index 9f12b5a33..8a64b3f71 100644 --- a/tests/php/Dev/DevAdminControllerTest.php +++ b/tests/php/Dev/DevAdminControllerTest.php @@ -14,7 +14,7 @@ use SilverStripe\Dev\Tests\DevAdminControllerTest\Controller1; class DevAdminControllerTest extends FunctionalTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -43,8 +43,8 @@ class DevAdminControllerTest extends FunctionalTest { // Check for the controller running from the registered url above // (we use contains rather than equals because sometimes you get a warning) - $this->assertContains(Controller1::OK_MSG, $this->getCapture('/dev/x1')); - $this->assertContains(Controller1::OK_MSG, $this->getCapture('/dev/x1/y1')); + $this->assertStringContainsString(Controller1::OK_MSG, $this->getCapture('/dev/x1')); + $this->assertStringContainsString(Controller1::OK_MSG, $this->getCapture('/dev/x1/y1')); } public function testGoodRegisteredControllerStatus() diff --git a/tests/php/Dev/FixtureBlueprintTest.php b/tests/php/Dev/FixtureBlueprintTest.php index b51946d96..6224d5783 100644 --- a/tests/php/Dev/FixtureBlueprintTest.php +++ b/tests/php/Dev/FixtureBlueprintTest.php @@ -144,12 +144,10 @@ class FixtureBlueprintTest extends SapphireTest $this->assertNotNull($obj2->HasManyRelation()->find('ID', $relation2->ID)); } - /** - * @expectedException InvalidArgumentException - * @expectedExceptionMessage No fixture definitions found - */ public function testCreateWithInvalidRelationName() { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('No fixture definitions found'); $blueprint = new FixtureBlueprint(TestDataObject::class); $obj = $blueprint->createObject( @@ -165,12 +163,10 @@ class FixtureBlueprintTest extends SapphireTest ); } - /** - * @expectedException InvalidArgumentException - * @expectedExceptionMessage No fixture definitions found - */ public function testCreateWithInvalidRelationIdentifier() { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('No fixture definitions found'); $blueprint = new FixtureBlueprint(TestDataObject::class); $obj = $blueprint->createObject( @@ -186,12 +182,10 @@ class FixtureBlueprintTest extends SapphireTest ); } - /** - * @expectedException InvalidArgumentException - * @expectedExceptionMessage Invalid format - */ public function testCreateWithInvalidRelationFormat() { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid format'); $factory = new FixtureFactory(); $blueprint = new FixtureBlueprint(TestDataObject::class); diff --git a/tests/php/Dev/SSListExporterTest.php b/tests/php/Dev/SSListExporterTest.php index d4df477ed..c236f209c 100644 --- a/tests/php/Dev/SSListExporterTest.php +++ b/tests/php/Dev/SSListExporterTest.php @@ -18,7 +18,7 @@ class SSListExporterTest extends SapphireTest */ private $exporter; - public function setUp() + protected function setUp(): void { parent::setUp(); $this->exporter = new SSListExporter(); diff --git a/tests/php/Dev/SapphireTestTest.php b/tests/php/Dev/SapphireTestTest.php index a29e75821..3b571c3c1 100644 --- a/tests/php/Dev/SapphireTestTest.php +++ b/tests/php/Dev/SapphireTestTest.php @@ -2,6 +2,7 @@ namespace SilverStripe\Dev\Tests; +use PHPUnit\Framework\ExpectationFailedException; use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\ArrayList; use SilverStripe\Security\Member; @@ -122,11 +123,10 @@ class SapphireTestTest extends SapphireTest * @param $itemsForList * * @testdox assertion assertListAllMatch fails when not all items are matching - * - * @expectedException \PHPUnit_Framework_ExpectationFailedException */ public function testAssertListAllMatchFailsWhenNotMatchingAllItems($match, $itemsForList) { + $this->expectException(ExpectationFailedException::class); $list = $this->generateArrayListFromItems($itemsForList); $this->assertListAllMatch($match, $list); @@ -156,11 +156,10 @@ class SapphireTestTest extends SapphireTest * * @param $matches * @param $itemsForList array - * - * @expectedException \PHPUnit_Framework_ExpectationFailedException */ public function testAssertListContainsFailsIfListDoesNotContainMatch($matches, $itemsForList) { + $this->expectException(ExpectationFailedException::class); $list = $this->generateArrayListFromItems($itemsForList); $list->push(Member::create(['FirstName' => 'Foo', 'Surname' => 'Foo'])); $list->push(Member::create(['FirstName' => 'Bar', 'Surname' => 'Bar'])); @@ -191,11 +190,10 @@ class SapphireTestTest extends SapphireTest * @param $itemsForList * * @testdox assertion assertListNotContains throws a exception when a matching item is found in the list - * - * @expectedException \PHPUnit_Framework_ExpectationFailedException */ public function testAssertListNotContainsFailsWhenListContainsAMatch($matches, $itemsForList) { + $this->expectException(ExpectationFailedException::class); $list = $this->generateArrayListFromItems($itemsForList); $list->push(Member::create(['FirstName' => 'Foo', 'Surname' => 'Foo'])); $list->push(Member::create(['FirstName' => 'Bar', 'Surname' => 'Bar'])); @@ -224,11 +222,10 @@ class SapphireTestTest extends SapphireTest * * @param $matches * @param $itemsForList - * - * @expectedException \PHPUnit_Framework_ExpectationFailedException */ public function testAssertListEqualsFailsOnNonEqualLists($matches, $itemsForList) { + $this->expectException(ExpectationFailedException::class); $list = $this->generateArrayListFromItems($itemsForList); $this->assertListEquals($matches, $list); diff --git a/tests/php/Dev/YamlFixtureTest.php b/tests/php/Dev/YamlFixtureTest.php index 4349940de..c18fe391d 100644 --- a/tests/php/Dev/YamlFixtureTest.php +++ b/tests/php/Dev/YamlFixtureTest.php @@ -45,11 +45,9 @@ class YamlFixtureTest extends SapphireTest $this->assertNull($obj->getFixtureFile()); } - /** - * @expectedException InvalidArgumentException - */ public function testFailsWithInvalidFixturePath() { + $this->expectException(\InvalidArgumentException::class); $invalidPath = ltrim(FRAMEWORK_DIR . '/tests/testing/invalid.yml', '/'); $obj = Injector::inst()->create(YamlFixture::class, $invalidPath); } diff --git a/tests/php/Forms/CheckboxSetFieldMultiEnumTest.php b/tests/php/Forms/CheckboxSetFieldMultiEnumTest.php index 8cbbf813f..13c5c4238 100644 --- a/tests/php/Forms/CheckboxSetFieldMultiEnumTest.php +++ b/tests/php/Forms/CheckboxSetFieldMultiEnumTest.php @@ -26,7 +26,7 @@ class CheckboxSetFieldMulitEnumTest extends SapphireTest } } - public function setUp() + protected function setUp(): void { if (!(DB::get_conn() instanceof MySQLDatabase)) { $this->markTestSkipped('DBMultiEnum only supported by MySQL'); @@ -35,7 +35,7 @@ class CheckboxSetFieldMulitEnumTest extends SapphireTest parent::setUp(); } - public function tearDown() + protected function tearDown(): void { if (!(DB::get_conn() instanceof MySQLDatabase)) { return; diff --git a/tests/php/Forms/CheckboxSetFieldTest.php b/tests/php/Forms/CheckboxSetFieldTest.php index 63bca0ad8..9a723bcba 100644 --- a/tests/php/Forms/CheckboxSetFieldTest.php +++ b/tests/php/Forms/CheckboxSetFieldTest.php @@ -359,13 +359,13 @@ class CheckboxSetFieldTest extends SapphireTest ] ); $fieldHTML = (string)$field1->Field(); - $this->assertContains('One', $fieldHTML); - $this->assertContains('Two & Three', $fieldHTML); - $this->assertNotContains('Two & Three', $fieldHTML); - $this->assertContains('Four & Five & Six', $fieldHTML); - $this->assertNotContains('Four & Five & Six', $fieldHTML); - $this->assertContains('<firstname>', $fieldHTML); - $this->assertNotContains('', $fieldHTML); + $this->assertStringContainsString('One', $fieldHTML); + $this->assertStringContainsString('Two & Three', $fieldHTML); + $this->assertStringNotContainsString('Two & Three', $fieldHTML); + $this->assertStringContainsString('Four & Five & Six', $fieldHTML); + $this->assertStringNotContainsString('Four & Five & Six', $fieldHTML); + $this->assertStringContainsString('<firstname>', $fieldHTML); + $this->assertStringNotContainsString('', $fieldHTML); } /** diff --git a/tests/php/Forms/CompositeFieldTest.php b/tests/php/Forms/CompositeFieldTest.php index 6bc72cda4..1cc710ed0 100644 --- a/tests/php/Forms/CompositeFieldTest.php +++ b/tests/php/Forms/CompositeFieldTest.php @@ -134,9 +134,9 @@ class CompositeFieldTest extends SapphireTest $field->setColumnCount(3); $result = $field->extraClass(); - $this->assertContains('field', $result, 'Default class was not added'); - $this->assertContains('CompositeField', $result, 'Default class was not added'); - $this->assertContains('multicolumn', $result, 'Multi column field did not have extra class added'); + $this->assertStringContainsString('field', $result, 'Default class was not added'); + $this->assertStringContainsString('CompositeField', $result, 'Default class was not added'); + $this->assertStringContainsString('multicolumn', $result, 'Multi column field did not have extra class added'); } public function testGetAttributes() @@ -163,7 +163,7 @@ class CompositeFieldTest extends SapphireTest public function testCollateDataFieldsThrowsErrorOnDuplicateChildren() { $this->expectException(\RuntimeException::class); - $this->expectExceptionMessageRegExp( + $this->expectExceptionMessageMatches( "/a field called 'Test' appears twice in your form.*TextField.*TextField/" ); @@ -266,8 +266,8 @@ class CompositeFieldTest extends SapphireTest $field->setName('TestComposite'); $result = $field->debug(); - $this->assertContains(CompositeField::class . ' (TestComposite)', $result); - $this->assertContains('TestTextField', $result); - $this->assertContains(''); + $this->assertStringContainsString(CompositeField::class . ' (TestComposite)', $result); + $this->assertStringContainsString('TestTextField', $result); + $this->assertStringContainsString(''); } } diff --git a/tests/php/Forms/ConfirmedPasswordFieldTest.php b/tests/php/Forms/ConfirmedPasswordFieldTest.php index 2f4face19..20be81893 100644 --- a/tests/php/Forms/ConfirmedPasswordFieldTest.php +++ b/tests/php/Forms/ConfirmedPasswordFieldTest.php @@ -16,7 +16,7 @@ class ConfirmedPasswordFieldTest extends SapphireTest { protected $usesDatabase = true; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -67,12 +67,12 @@ class ConfirmedPasswordFieldTest extends SapphireTest //hide by default and display show/hide toggle button $field = new ConfirmedPasswordField('Test', 'Testing', 'valueA', null, true); $fieldHTML = $field->Field(); - $this->assertContains( + $this->assertStringContainsString( "showOnClickContainer", $fieldHTML, "Test class for hiding/showing the form contents is set" ); - $this->assertContains( + $this->assertStringContainsString( "showOnClick", $fieldHTML, "Test class for hiding/showing the form contents is set" @@ -81,12 +81,12 @@ class ConfirmedPasswordFieldTest extends SapphireTest //show all by default $field = new ConfirmedPasswordField('Test', 'Testing', 'valueA', null, false); $fieldHTML = $field->Field(); - $this->assertNotContains( + $this->assertStringNotContainsString( "showOnClickContainer", $fieldHTML, "Test class for hiding/showing the form contents is set" ); - $this->assertNotContains( + $this->assertStringNotContainsString( "showOnClick", $fieldHTML, "Test class for hiding/showing the form contents is set" @@ -200,7 +200,7 @@ class ConfirmedPasswordFieldTest extends SapphireTest $this->assertSame($expectValid, $result, 'Validate method should return its result'); $this->assertSame($expectValid, $validator->getResult()->isValid()); if ($expectedMessage) { - $this->assertContains($expectedMessage, $validator->getResult()->serialize()); + $this->assertStringContainsString($expectedMessage, $validator->getResult()->serialize()); } } @@ -233,7 +233,7 @@ class ConfirmedPasswordFieldTest extends SapphireTest $this->assertFalse($result, 'Validate method should return its result'); $this->assertFalse($validator->getResult()->isValid()); - $this->assertContains( + $this->assertStringContainsString( 'Passwords must have at least one digit and one alphanumeric character', $validator->getResult()->serialize() ); @@ -252,7 +252,7 @@ class ConfirmedPasswordFieldTest extends SapphireTest $this->assertFalse($result, 'Validate method should return its result'); $this->assertFalse($validator->getResult()->isValid()); - $this->assertContains( + $this->assertStringContainsString( 'You must enter your current password', $validator->getResult()->serialize() ); @@ -274,7 +274,7 @@ class ConfirmedPasswordFieldTest extends SapphireTest $this->assertFalse($result, 'Validate method should return its result'); $this->assertFalse($validator->getResult()->isValid()); - $this->assertContains( + $this->assertStringContainsString( 'You must be logged in to change your password', $validator->getResult()->serialize() ); @@ -300,7 +300,7 @@ class ConfirmedPasswordFieldTest extends SapphireTest $this->assertFalse($result, 'Validate method should return its result'); $this->assertFalse($validator->getResult()->isValid()); - $this->assertContains( + $this->assertStringContainsString( 'The current password you have entered is not correct', $validator->getResult()->serialize() ); @@ -357,7 +357,7 @@ class ConfirmedPasswordFieldTest extends SapphireTest $this->assertInstanceOf(ReadonlyField::class, $result); $this->assertSame('Change it', $result->Title()); - $this->assertContains('***', $result->Value()); + $this->assertStringContainsString('***', $result->Value()); } public function testPerformDisabledTransformation() diff --git a/tests/php/Forms/CurrencyFieldDisabledTest.php b/tests/php/Forms/CurrencyFieldDisabledTest.php index a36efec58..6f1cc0c70 100644 --- a/tests/php/Forms/CurrencyFieldDisabledTest.php +++ b/tests/php/Forms/CurrencyFieldDisabledTest.php @@ -13,9 +13,9 @@ class CurrencyFieldDisabledTest extends SapphireTest $field = new CurrencyField_Disabled('Test', '', '$5.00'); $result = $field->Field(); - $this->assertContains('assertContains('disabled', $result, 'The input should be disabled'); - $this->assertContains('$5.00', $result, 'The value should be rendered'); + $this->assertStringContainsString('assertStringContainsString('disabled', $result, 'The input should be disabled'); + $this->assertStringContainsString('$5.00', $result, 'The value should be rendered'); } /** @@ -27,8 +27,8 @@ class CurrencyFieldDisabledTest extends SapphireTest $field = new CurrencyField_Disabled('Test', '', '€5.00'); $result = $field->Field(); - $this->assertContains('assertContains('disabled', $result, 'The input should be disabled'); - $this->assertContains('€5.00', $result, 'The value should be rendered'); + $this->assertStringContainsString('assertStringContainsString('disabled', $result, 'The input should be disabled'); + $this->assertStringContainsString('€5.00', $result, 'The value should be rendered'); } } diff --git a/tests/php/Forms/CurrencyFieldReadonlyTest.php b/tests/php/Forms/CurrencyFieldReadonlyTest.php index d403126e7..0c998a8ef 100644 --- a/tests/php/Forms/CurrencyFieldReadonlyTest.php +++ b/tests/php/Forms/CurrencyFieldReadonlyTest.php @@ -21,9 +21,9 @@ class CurrencyFieldReadonlyTest extends SapphireTest $field = new CurrencyField_Readonly('Test', '', '$5.00'); $result = $field->Field(); - $this->assertContains('assertContains('readonly', $result, 'The input should be readonly'); - $this->assertContains('$5.00', $result, 'The value should be rendered'); + $this->assertStringContainsString('assertStringContainsString('readonly', $result, 'The input should be readonly'); + $this->assertStringContainsString('$5.00', $result, 'The value should be rendered'); } public function testFieldWithOutValue() @@ -32,9 +32,9 @@ class CurrencyFieldReadonlyTest extends SapphireTest $field = new CurrencyField_Readonly('Test', '', null); $result = $field->Field(); - $this->assertContains('assertContains('readonly', $result, 'The input should be readonly'); - $this->assertContains('AUD0.00', $result, 'The value should be rendered'); + $this->assertStringContainsString('assertStringContainsString('readonly', $result, 'The input should be readonly'); + $this->assertStringContainsString('AUD0.00', $result, 'The value should be rendered'); } /** @@ -46,8 +46,8 @@ class CurrencyFieldReadonlyTest extends SapphireTest $field = new CurrencyField_Readonly('Test', '', '€5.00'); $result = $field->Field(); - $this->assertContains('assertContains('readonly', $result, 'The input should be readonly'); - $this->assertContains('€5.00', $result, 'The value should be rendered'); + $this->assertStringContainsString('assertStringContainsString('readonly', $result, 'The input should be readonly'); + $this->assertStringContainsString('€5.00', $result, 'The value should be rendered'); } } diff --git a/tests/php/Forms/CurrencyFieldTest.php b/tests/php/Forms/CurrencyFieldTest.php index dbb595996..02c4114e4 100644 --- a/tests/php/Forms/CurrencyFieldTest.php +++ b/tests/php/Forms/CurrencyFieldTest.php @@ -307,6 +307,6 @@ class CurrencyFieldTest extends SapphireTest $this->assertFalse($result, 'Validation should fail since wrong currency was used'); $this->assertFalse($validator->getResult()->isValid(), 'Validator should receive failed state'); - $this->assertContains('Please enter a valid currency', $validator->getResult()->serialize()); + $this->assertStringContainsString('Please enter a valid currency', $validator->getResult()->serialize()); } } diff --git a/tests/php/Forms/DatalessFieldTest.php b/tests/php/Forms/DatalessFieldTest.php index a67cfc9a6..abfdf54ac 100644 --- a/tests/php/Forms/DatalessFieldTest.php +++ b/tests/php/Forms/DatalessFieldTest.php @@ -2,7 +2,7 @@ namespace SilverStripe\Forms; -use PHPUnit_Framework_MockObject_MockObject; +use PHPUnit\Framework\MockObject\MockObject; use SilverStripe\Dev\SapphireTest; class DatalessFieldTest extends SapphireTest @@ -16,7 +16,7 @@ class DatalessFieldTest extends SapphireTest public function testFieldHolderAndSmallFieldHolderReturnField() { - /** @var DatalessField|PHPUnit_Framework_MockObject_MockObject $mock */ + /** @var DatalessField|MockObject $mock */ $mock = $this->getMockBuilder(DatalessField::class) ->disableOriginalConstructor() ->setMethods(['Field']) diff --git a/tests/php/Forms/DateFieldDisabledTest.php b/tests/php/Forms/DateFieldDisabledTest.php index 6fffdcd13..b3f66b5c5 100644 --- a/tests/php/Forms/DateFieldDisabledTest.php +++ b/tests/php/Forms/DateFieldDisabledTest.php @@ -12,7 +12,7 @@ use SilverStripe\ORM\FieldType\DBDatetime; */ class DateFieldDisabledTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); i18n::set_locale('en_NZ'); @@ -79,7 +79,7 @@ class DateFieldDisabledTest extends SapphireTest { $field = new DateField_Disabled('Test'); $result = $field->Type(); - $this->assertContains('readonly', $result, 'Disabled field should be treated as readonly'); - $this->assertContains('date_disabled', $result, 'Field should contain date_disabled class'); + $this->assertStringContainsString('readonly', $result, 'Disabled field should be treated as readonly'); + $this->assertStringContainsString('date_disabled', $result, 'Field should contain date_disabled class'); } } diff --git a/tests/php/Forms/DateFieldTest.php b/tests/php/Forms/DateFieldTest.php index 87065fc8a..55bbb15ab 100644 --- a/tests/php/Forms/DateFieldTest.php +++ b/tests/php/Forms/DateFieldTest.php @@ -3,6 +3,7 @@ namespace SilverStripe\Forms\Tests; use IntlDateFormatter; +use LogicException; use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\DateField; use SilverStripe\Forms\DateField_Disabled; @@ -16,7 +17,7 @@ use SilverStripe\ORM\FieldType\DBDatetime; */ class DateFieldTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); i18n::set_locale('en_NZ'); @@ -192,36 +193,30 @@ class DateFieldTest extends SapphireTest ); } - /** - * @expectedException \LogicException - * @expectedExceptionMessageRegExp /Please opt-out .* if using setDateFormat/ - */ public function testHtml5WithCustomFormatThrowsException() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessageMatches('/Please opt-out .* if using setDateFormat/'); $dateField = new DateField('Date', 'Date'); $dateField->setValue('2010-03-31'); $dateField->setDateFormat('d/M/y'); $dateField->Value(); } - /** - * @expectedException \LogicException - * @expectedExceptionMessageRegExp /Please opt-out .* if using setDateLength/ - */ public function testHtml5WithCustomDateLengthThrowsException() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessageMatches('/Please opt-out .* if using setDateLength/'); $dateField = new DateField('Date', 'Date'); $dateField->setValue('2010-03-31'); $dateField->setDateLength(IntlDateFormatter::MEDIUM); $dateField->Value(); } - /** - * @expectedException \LogicException - * @expectedExceptionMessageRegExp /Please opt-out .* if using setLocale/ - */ public function testHtml5WithCustomLocaleThrowsException() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessageMatches('/Please opt-out .* if using setLocale/'); $dateField = new DateField('Date', 'Date'); $dateField->setValue('2010-03-31'); $dateField->setLocale('de_DE'); diff --git a/tests/php/Forms/DatetimeFieldTest.php b/tests/php/Forms/DatetimeFieldTest.php index ec36a0ab8..6fa5e39a7 100644 --- a/tests/php/Forms/DatetimeFieldTest.php +++ b/tests/php/Forms/DatetimeFieldTest.php @@ -17,7 +17,7 @@ class DatetimeFieldTest extends SapphireTest { protected $timezone = null; - protected function setUp() + protected function setUp(): void { parent::setUp(); i18n::set_locale('en_NZ'); @@ -26,7 +26,7 @@ class DatetimeFieldTest extends SapphireTest $this->timezone = date_default_timezone_get(); } - protected function tearDown() + protected function tearDown(): void { DBDatetime::clear_mock_now(); date_default_timezone_set($this->timezone); @@ -146,7 +146,7 @@ class DatetimeFieldTest extends SapphireTest $this->assertEquals($datetimeField->dataValue(), '2003-03-29 23:00:00'); // Some localisation packages exclude the ',' in default medium format - $this->assertRegExp( + $this->assertMatchesRegularExpression( '#29/03/2003(,)? 11:00:00 (PM|pm)#', $datetimeField->Value(), 'User value is formatted, and in user timezone' @@ -490,12 +490,10 @@ class DatetimeFieldTest extends SapphireTest $this->assertTrue($result->isReadonly()); } - /** - * @expectedException \BadMethodCallException - * @expectedExceptionMessage Can't change timezone after setting a value - */ public function testSetTimezoneThrowsExceptionWhenChangingTimezoneAfterSettingValue() { + $this->expectException(\BadMethodCallException::class); + $this->expectExceptionMessage("Can't change timezone after setting a value"); date_default_timezone_set('Europe/Berlin'); $field = new DatetimeField('Datetime', 'Time', '2003-03-29 23:59:38'); $field->setTimezone('Pacific/Auckland'); diff --git a/tests/php/Forms/DefaultFormFactoryTest.php b/tests/php/Forms/DefaultFormFactoryTest.php index c8ab715f3..f322f0a34 100644 --- a/tests/php/Forms/DefaultFormFactoryTest.php +++ b/tests/php/Forms/DefaultFormFactoryTest.php @@ -9,12 +9,10 @@ use SilverStripe\ORM\DataObject; class DefaultFormFactoryTest extends SapphireTest { - /** - * @expectedException InvalidArgumentException - * @expectedExceptionMessageRegExp /Missing required context/ - */ public function testGetFormThrowsExceptionOnMissingContext() { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessageMatches('/Missing required context/'); $factory = new DefaultFormFactory(); $factory->getForm(); } diff --git a/tests/php/Forms/EmailFieldTest.php b/tests/php/Forms/EmailFieldTest.php index 85733d8a6..75e5e33de 100644 --- a/tests/php/Forms/EmailFieldTest.php +++ b/tests/php/Forms/EmailFieldTest.php @@ -5,7 +5,7 @@ namespace SilverStripe\Forms\Tests; use SilverStripe\Dev\FunctionalTest; use SilverStripe\Forms\EmailField; use Exception; -use PHPUnit_Framework_AssertionFailedError; +use PHPUnit\Framework\AssertionFailedError; use SilverStripe\Forms\Tests\EmailFieldTest\TestValidator; /** @@ -51,7 +51,7 @@ class EmailFieldTest extends FunctionalTest // If we expect failure and processing gets here without an exception, the test failed $this->assertTrue($expectSuccess, $checkText . " (/$email/ passed validation, but not expected to)"); } catch (Exception $e) { - if ($e instanceof PHPUnit_Framework_AssertionFailedError) { + if ($e instanceof AssertionFailedError) { // re-throw assertion failure throw $e; } elseif ($expectSuccess) { @@ -77,6 +77,6 @@ class EmailFieldTest extends FunctionalTest ['Email' => 'test@test.com'] ); - $this->assertContains('Test save was successful', $response->getBody()); + $this->assertStringContainsString('Test save was successful', $response->getBody()); } } diff --git a/tests/php/Forms/FormActionTest.php b/tests/php/Forms/FormActionTest.php index 328aadb79..0ce07c279 100644 --- a/tests/php/Forms/FormActionTest.php +++ b/tests/php/Forms/FormActionTest.php @@ -11,10 +11,10 @@ class FormActionTest extends SapphireTest public function testGetField() { $formAction = new FormAction('test'); - $this->assertContains('type="submit"', $formAction->getAttributesHTML()); + $this->assertStringContainsString('type="submit"', $formAction->getAttributesHTML()); $formAction->setAttribute('src', 'file.png'); - $this->assertContains('type="image"', $formAction->getAttributesHTML()); + $this->assertStringContainsString('type="image"', $formAction->getAttributesHTML()); } public function testGetTitle() diff --git a/tests/php/Forms/FormFactoryTest.php b/tests/php/Forms/FormFactoryTest.php index 67242c3e9..8cac9edc4 100644 --- a/tests/php/Forms/FormFactoryTest.php +++ b/tests/php/Forms/FormFactoryTest.php @@ -28,7 +28,7 @@ class FormFactoryTest extends SapphireTest return []; } - public function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Forms/FormFieldTest.php b/tests/php/Forms/FormFieldTest.php index 8f60cddbb..24d59fee9 100644 --- a/tests/php/Forms/FormFieldTest.php +++ b/tests/php/Forms/FormFieldTest.php @@ -2,10 +2,10 @@ namespace SilverStripe\Forms\Tests; +use LogicException; use ReflectionClass; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Config\Config; -use SilverStripe\Core\Convert; use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\CompositeField; use SilverStripe\Forms\FieldList; @@ -40,7 +40,7 @@ class FormFieldTest extends SapphireTest $field = new FormField('MyField'); - $this->assertContains('class1', $field->extraClass(), 'Class list does not contain expected class'); + $this->assertStringContainsString('class1', $field->extraClass(), 'Class list does not contain expected class'); FormField::config()->update( 'default_classes', @@ -52,7 +52,7 @@ class FormFieldTest extends SapphireTest $field = new FormField('MyField'); - $this->assertContains('class1 class2', $field->extraClass(), 'Class list does not contain expected class'); + $this->assertStringContainsString('class1 class2', $field->extraClass(), 'Class list does not contain expected class'); FormField::config()->update( 'default_classes', @@ -63,11 +63,11 @@ class FormFieldTest extends SapphireTest $field = new FormField('MyField'); - $this->assertContains('class3', $field->extraClass(), 'Class list does not contain expected class'); + $this->assertStringContainsString('class3', $field->extraClass(), 'Class list does not contain expected class'); $field->removeExtraClass('class3'); - $this->assertNotContains('class3', $field->extraClass(), 'Class list contains unexpected class'); + $this->assertStringNotContainsString('class3', $field->extraClass(), 'Class list contains unexpected class'); TextField::config()->update( 'default_classes', @@ -79,8 +79,8 @@ class FormFieldTest extends SapphireTest $field = new TextField('MyField'); //check default classes inherit - $this->assertContains('class3', $field->extraClass(), 'Class list does not contain inherited class'); - $this->assertContains('textfield-class', $field->extraClass(), 'Class list does not contain expected class'); + $this->assertStringContainsString('class3', $field->extraClass(), 'Class list does not contain inherited class'); + $this->assertStringContainsString('textfield-class', $field->extraClass(), 'Class list does not contain expected class'); Config::unnest(); } @@ -159,35 +159,35 @@ class FormFieldTest extends SapphireTest $field = new FormField('MyField'); $field->setAttribute('foo', 'bar'); - $this->assertContains('foo="bar"', $field->getAttributesHTML()); + $this->assertStringContainsString('foo="bar"', $field->getAttributesHTML()); $field->setAttribute('foo', null); - $this->assertNotContains('foo=', $field->getAttributesHTML()); + $this->assertStringNotContainsString('foo=', $field->getAttributesHTML()); $field->setAttribute('foo', ''); - $this->assertNotContains('foo=', $field->getAttributesHTML()); + $this->assertStringNotContainsString('foo=', $field->getAttributesHTML()); $field->setAttribute('foo', false); - $this->assertNotContains('foo=', $field->getAttributesHTML()); + $this->assertStringNotContainsString('foo=', $field->getAttributesHTML()); $field->setAttribute('foo', true); - $this->assertContains('foo="foo"', $field->getAttributesHTML()); + $this->assertStringContainsString('foo="foo"', $field->getAttributesHTML()); $field->setAttribute('foo', 'false'); - $this->assertContains('foo="false"', $field->getAttributesHTML()); + $this->assertStringContainsString('foo="false"', $field->getAttributesHTML()); $field->setAttribute('foo', 'true'); - $this->assertContains('foo="true"', $field->getAttributesHTML()); + $this->assertStringContainsString('foo="true"', $field->getAttributesHTML()); $field->setAttribute('foo', 0); - $this->assertContains('foo="0"', $field->getAttributesHTML()); + $this->assertStringContainsString('foo="0"', $field->getAttributesHTML()); $field->setAttribute('one', 1); $field->setAttribute('two', 2); $field->setAttribute('three', 3); - $this->assertNotContains('one="1"', $field->getAttributesHTML('one', 'two')); - $this->assertNotContains('two="2"', $field->getAttributesHTML('one', 'two')); - $this->assertContains('three="3"', $field->getAttributesHTML('one', 'two')); + $this->assertStringNotContainsString('one="1"', $field->getAttributesHTML('one', 'two')); + $this->assertStringNotContainsString('two="2"', $field->getAttributesHTML('one', 'two')); + $this->assertStringContainsString('three="3"', $field->getAttributesHTML('one', 'two')); } /** @@ -241,18 +241,18 @@ class FormFieldTest extends SapphireTest { $field = new FormField('MyField'); $field->setReadonly(true); - $this->assertContains('readonly="readonly"', $field->getAttributesHTML()); + $this->assertStringContainsString('readonly="readonly"', $field->getAttributesHTML()); $field->setReadonly(false); - $this->assertNotContains('readonly="readonly"', $field->getAttributesHTML()); + $this->assertStringNotContainsString('readonly="readonly"', $field->getAttributesHTML()); } public function testDisabled() { $field = new FormField('MyField'); $field->setDisabled(true); - $this->assertContains('disabled="disabled"', $field->getAttributesHTML()); + $this->assertStringContainsString('disabled="disabled"', $field->getAttributesHTML()); $field->setDisabled(false); - $this->assertNotContains('disabled="disabled"', $field->getAttributesHTML()); + $this->assertStringNotContainsString('disabled="disabled"', $field->getAttributesHTML()); } public function testEveryFieldTransformsReadonlyAsClone() @@ -358,7 +358,7 @@ class FormFieldTest extends SapphireTest { $field = new FormField('MyField'); $schema = $field->getSchemaDataDefaults(); - $this->assertInternalType('array', $schema); + $this->assertIsArray($schema); } public function testGetSchemaDataDefaultsTitleTip() @@ -454,11 +454,9 @@ class FormFieldTest extends SapphireTest $this->assertSame('foo/field/Test/bar', $field->Link('bar')); } - /** - * @expectedException \LogicException - */ public function testLinkWithoutForm() { + $this->expectException(LogicException::class); $field = new FormField('Test'); $field->Link('bar'); } diff --git a/tests/php/Forms/FormSchemaTest.php b/tests/php/Forms/FormSchemaTest.php index 7af4d8d70..e873e5500 100644 --- a/tests/php/Forms/FormSchemaTest.php +++ b/tests/php/Forms/FormSchemaTest.php @@ -20,7 +20,7 @@ use SilverStripe\Forms\PopoverField; */ class FormSchemaTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -38,7 +38,7 @@ class FormSchemaTest extends SapphireTest $expected = json_decode(file_get_contents(__DIR__ . '/FormSchemaTest/testGetSchema.json'), true); $schema = $formSchema->getSchema($form); - $this->assertInternalType('array', $schema); + $this->assertIsArray($schema); $this->assertEquals($expected, $schema); } @@ -62,7 +62,7 @@ class FormSchemaTest extends SapphireTest ]; $state = $formSchema->getState($form); - $this->assertInternalType('array', $state); + $this->assertIsArray($state); $this->assertEquals($expected, $state); } @@ -92,7 +92,7 @@ class FormSchemaTest extends SapphireTest ]; $state = $formSchema->getState($form); - $this->assertInternalType('array', $state); + $this->assertIsArray($state); $this->assertJsonStringEqualsJsonString(json_encode($expected), json_encode($state)); } @@ -136,7 +136,7 @@ class FormSchemaTest extends SapphireTest ]; $state = $formSchema->getState($form); - $this->assertInternalType('array', $state); + $this->assertIsArray($state); $this->assertJsonStringEqualsJsonString(json_encode($expected), json_encode($state)); } @@ -167,7 +167,7 @@ class FormSchemaTest extends SapphireTest $expected = json_decode(file_get_contents(__DIR__ . '/FormSchemaTest/testGetNestedSchema.json'), true); $schema = $formSchema->getSchema($form); - $this->assertInternalType('array', $schema); + $this->assertIsArray($schema); $this->assertEquals($expected, $schema); } @@ -207,7 +207,7 @@ class FormSchemaTest extends SapphireTest $formSchema = new FormSchema(); $schema = $formSchema->getSchema($form); $expected = json_decode(file_get_contents(__DIR__ . '/FormSchemaTest/testSchemaValidation.json'), true); - $this->assertInternalType('array', $schema); + $this->assertIsArray($schema); $this->assertEquals($expected, $schema); } } diff --git a/tests/php/Forms/FormTest.php b/tests/php/Forms/FormTest.php index 8ee42df4b..f9fb8e51d 100644 --- a/tests/php/Forms/FormTest.php +++ b/tests/php/Forms/FormTest.php @@ -56,7 +56,7 @@ class FormTest extends FunctionalTest protected static $disable_themes = true; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -140,16 +140,16 @@ class FormTest extends FunctionalTest ); // Number field updates its value - $this->assertContains('getBody()); + $this->assertStringContainsString('getBody()); // Readonly field remains - $this->assertContains( + $this->assertStringContainsString( 'getBody() ); - $this->assertNotContains('hacxzored', $response->getBody()); + $this->assertStringNotContainsString('hacxzored', $response->getBody()); } public function testLoadDataFromUnchangedHandling() @@ -502,12 +502,12 @@ class FormTest extends FunctionalTest 'Required fields show a notification on field when left blank' ); - $this->assertContains( + $this->assertStringContainsString( ''<a href="http://mysite.com">link</a>' is not a number, only numbers can be accepted for this field', $response->getBody(), "Validation messages are safely XML encoded" ); - $this->assertNotContains( + $this->assertStringNotContainsString( 'link', $response->getBody(), "Unsafe content is not emitted directly inside the response body" @@ -788,7 +788,7 @@ class FormTest extends FunctionalTest $form = $this->getStubForm(); - $this->assertContains('class1', $form->extraClass(), 'Class list does not contain expected class'); + $this->assertStringContainsString('class1', $form->extraClass(), 'Class list does not contain expected class'); Form::config()->update( 'default_classes', @@ -800,7 +800,7 @@ class FormTest extends FunctionalTest $form = $this->getStubForm(); - $this->assertContains('class1 class2', $form->extraClass(), 'Class list does not contain expected class'); + $this->assertStringContainsString('class1 class2', $form->extraClass(), 'Class list does not contain expected class'); Form::config()->update( 'default_classes', @@ -811,11 +811,11 @@ class FormTest extends FunctionalTest $form = $this->getStubForm(); - $this->assertContains('class3', $form->extraClass(), 'Class list does not contain expected class'); + $this->assertStringContainsString('class3', $form->extraClass(), 'Class list does not contain expected class'); $form->removeExtraClass('class3'); - $this->assertNotContains('class3', $form->extraClass(), 'Class list contains unexpected class'); + $this->assertStringNotContainsString('class3', $form->extraClass(), 'Class list contains unexpected class'); } public function testAttributes() @@ -903,22 +903,22 @@ class FormTest extends FunctionalTest $form = $this->getStubForm(); $form->setAttribute('foo', 'bar'); - $this->assertContains('foo="bar"', $form->getAttributesHTML()); + $this->assertStringContainsString('foo="bar"', $form->getAttributesHTML()); $form->setAttribute('foo', null); - $this->assertNotContains('foo="bar"', $form->getAttributesHTML()); + $this->assertStringNotContainsString('foo="bar"', $form->getAttributesHTML()); $form->setAttribute('foo', true); - $this->assertContains('foo="foo"', $form->getAttributesHTML()); + $this->assertStringContainsString('foo="foo"', $form->getAttributesHTML()); $form->setAttribute('one', 1); $form->setAttribute('two', 2); $form->setAttribute('three', 3); $form->setAttribute('', ''); - $this->assertNotContains('one="1"', $form->getAttributesHTML('one', 'two')); - $this->assertNotContains('two="2"', $form->getAttributesHTML('one', 'two')); - $this->assertContains('three="3"', $form->getAttributesHTML('one', 'two')); - $this->assertNotContains('', $form->getAttributesHTML()); + $this->assertStringNotContainsString('one="1"', $form->getAttributesHTML('one', 'two')); + $this->assertStringNotContainsString('two="2"', $form->getAttributesHTML('one', 'two')); + $this->assertStringContainsString('three="3"', $form->getAttributesHTML('one', 'two')); + $this->assertStringNotContainsString('', $form->getAttributesHTML()); } function testMessageEscapeHtml() @@ -927,7 +927,7 @@ class FormTest extends FunctionalTest $form->setMessage('Escaped HTML', 'good', ValidationResult::CAST_TEXT); $parser = new CSSContentParser($form->forTemplate()); $messageEls = $parser->getBySelector('.message'); - $this->assertContains( + $this->assertStringContainsString( '<em>Escaped HTML</em>', $messageEls[0]->asXML() ); @@ -936,7 +936,7 @@ class FormTest extends FunctionalTest $form->setMessage('Unescaped HTML', 'good', ValidationResult::CAST_HTML); $parser = new CSSContentParser($form->forTemplate()); $messageEls = $parser->getBySelector('.message'); - $this->assertContains( + $this->assertStringContainsString( 'Unescaped HTML', $messageEls[0]->asXML() ); @@ -948,7 +948,7 @@ class FormTest extends FunctionalTest $form->Fields()->dataFieldByName('key1')->setMessage('Escaped HTML', 'good'); $parser = new CSSContentParser($result = $form->forTemplate()); $messageEls = $parser->getBySelector('#Form_Form_key1_Holder .message'); - $this->assertContains( + $this->assertStringContainsString( '<em>Escaped HTML</em>', $messageEls[0]->asXML() ); @@ -961,7 +961,7 @@ class FormTest extends FunctionalTest ->setMessage('Unescaped HTML', 'good', ValidationResult::CAST_HTML); $parser = new CSSContentParser($form->forTemplate()); $messageEls = $parser->getBySelector('#Form_Form_key1_Holder .message'); - $this->assertContains( + $this->assertStringContainsString( 'Unescaped HTML', $messageEls[0]->asXML() ); @@ -1055,25 +1055,25 @@ class FormTest extends FunctionalTest // Test our reloaded form field $body = $response->getBody(); - $this->assertContains( + $this->assertStringContainsString( 'assertContains( + $this->assertStringContainsString( 'clean($body), 'Our reloaded form should contain a SomeFrenchNumericField with the value "9 876,5432"' ); - $this->assertContains( + $this->assertStringContainsString( 'assertContains( + $this->assertStringContainsString( 'clean($body), 'Our reloaded form should contain a SomeFrenchMoneyField[Amount] with the value "9 876,54"' diff --git a/tests/php/Forms/GridField/GridFieldActionMenuTest.php b/tests/php/Forms/GridField/GridFieldActionMenuTest.php index 517947159..4404b6254 100644 --- a/tests/php/Forms/GridField/GridFieldActionMenuTest.php +++ b/tests/php/Forms/GridField/GridFieldActionMenuTest.php @@ -55,7 +55,7 @@ class GridFieldActionMenuTest extends SapphireTest Permissions::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->list = new DataList(Team::class); diff --git a/tests/php/Forms/GridField/GridFieldDataColumnsTest.php b/tests/php/Forms/GridField/GridFieldDataColumnsTest.php index c1f5ca9d5..c508f8e72 100644 --- a/tests/php/Forms/GridField/GridFieldDataColumnsTest.php +++ b/tests/php/Forms/GridField/GridFieldDataColumnsTest.php @@ -2,6 +2,7 @@ namespace SilverStripe\Forms\Tests\GridField; +use InvalidArgumentException; use SilverStripe\Forms\GridField\GridFieldDataColumns; use SilverStripe\Security\Member; use SilverStripe\Dev\SapphireTest; @@ -41,11 +42,10 @@ class GridFieldDataColumnsTest extends SapphireTest /** * @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::setDisplayFields * @covers \SilverStripe\Forms\GridField\GridFieldDataColumns::getDisplayFields - * - * @expectedException \InvalidArgumentException */ public function testGridFieldDisplayFieldsWithBadArguments() { + $this->expectException(InvalidArgumentException::class); $obj = new GridField('testfield', 'testfield', Member::get()); $columns = $obj->getConfig()->getComponentByType(GridFieldDataColumns::class); $columns->setDisplayFields(new stdClass()); diff --git a/tests/php/Forms/GridField/GridFieldDeleteActionTest.php b/tests/php/Forms/GridField/GridFieldDeleteActionTest.php index 4f2005b03..bb01599a7 100644 --- a/tests/php/Forms/GridField/GridFieldDeleteActionTest.php +++ b/tests/php/Forms/GridField/GridFieldDeleteActionTest.php @@ -56,7 +56,7 @@ class GridFieldDeleteActionTest extends SapphireTest Permissions::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->list = new DataList(Team::class); diff --git a/tests/php/Forms/GridField/GridFieldEditButtonTest.php b/tests/php/Forms/GridField/GridFieldEditButtonTest.php index d5a14b902..b3a08394c 100644 --- a/tests/php/Forms/GridField/GridFieldEditButtonTest.php +++ b/tests/php/Forms/GridField/GridFieldEditButtonTest.php @@ -52,7 +52,7 @@ class GridFieldEditButtonTest extends SapphireTest Permissions::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->list = new DataList(Team::class); @@ -100,7 +100,7 @@ class GridFieldEditButtonTest extends SapphireTest $result = $button->getExtraClass(); foreach ($expected as $className) { - $this->assertContains($className, $result); + $this->assertStringContainsString($className, $result); } } @@ -109,15 +109,15 @@ class GridFieldEditButtonTest extends SapphireTest $button = new GridFieldEditButton; $button->addExtraClass('foobar'); - $this->assertContains('foobar', $button->getExtraClass()); + $this->assertStringContainsString('foobar', $button->getExtraClass()); $button->removeExtraClass('foobar'); - $this->assertNotContains('foobar', $button->getExtraClass()); + $this->assertStringNotContainsString('foobar', $button->getExtraClass()); // Check that duplicates are removed $button->addExtraClass('foobar'); $button->addExtraClass('foobar'); $button->removeExtraClass('foobar'); - $this->assertNotContains('foobar', $button->getExtraClass()); + $this->assertStringNotContainsString('foobar', $button->getExtraClass()); } } diff --git a/tests/php/Forms/GridField/GridFieldExportButtonTest.php b/tests/php/Forms/GridField/GridFieldExportButtonTest.php index 222d5f657..3496332b4 100644 --- a/tests/php/Forms/GridField/GridFieldExportButtonTest.php +++ b/tests/php/Forms/GridField/GridFieldExportButtonTest.php @@ -35,7 +35,7 @@ class GridFieldExportButtonTest extends SapphireTest NoView::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php b/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php index 91e1a14f3..8ce32a97a 100644 --- a/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php +++ b/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php @@ -50,7 +50,7 @@ class GridFieldFilterHeaderTest extends SapphireTest Mom::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->list = new DataList(Team::class); @@ -70,8 +70,8 @@ class GridFieldFilterHeaderTest extends SapphireTest $htmlFragment = $this->component->getHTMLFragments($this->gridField); // Check that the output is the new search field - $this->assertContains('
assertContains('Open search and filter', $htmlFragment['buttons-before-right']); + $this->assertStringContainsString('
assertStringContainsString('Open search and filter', $htmlFragment['buttons-before-right']); $this->gridField->getConfig()->removeComponentsByType(GridFieldFilterHeader::class); $this->gridField->getConfig()->addComponent(new GridFieldFilterHeader(true)); @@ -79,7 +79,7 @@ class GridFieldFilterHeaderTest extends SapphireTest $htmlFragment = $this->component->getHTMLFragments($this->gridField); // Check that the output is the legacy filter header - $this->assertContains( + $this->assertStringContainsString( '', $htmlFragment['header'] ); diff --git a/tests/php/Forms/GridField/GridFieldLazyLoaderTest.php b/tests/php/Forms/GridField/GridFieldLazyLoaderTest.php index 553f6ae03..9789fe08c 100644 --- a/tests/php/Forms/GridField/GridFieldLazyLoaderTest.php +++ b/tests/php/Forms/GridField/GridFieldLazyLoaderTest.php @@ -44,7 +44,7 @@ class GridFieldLazyLoaderTest extends SapphireTest Team::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->list = DataList::create(Team::class); @@ -89,8 +89,8 @@ class GridFieldLazyLoaderTest extends SapphireTest $gridField = $this->getHeaderlessGridField(); $actual = $this->component->getHTMLFragments($gridField); $this->assertEmpty($actual, 'getHTMLFragments should always return an array'); - $this->assertContains('grid-field--lazy-loadable', $gridField->extraClass()); - $this->assertNotContains('grid-field--lazy-loaded', $gridField->extraClass()); + $this->assertStringContainsString('grid-field--lazy-loadable', $gridField->extraClass()); + $this->assertStringNotContainsString('grid-field--lazy-loaded', $gridField->extraClass()); } public function testGetHTMLFragmentsWithoutTabSet() @@ -98,8 +98,8 @@ class GridFieldLazyLoaderTest extends SapphireTest $gridField = $this->getOutOfTabSetGridField(); $actual = $this->component->getHTMLFragments($gridField); $this->assertEmpty($actual, 'getHTMLFragments should always return an array'); - $this->assertContains('grid-field--lazy-loaded', $gridField->extraClass()); - $this->assertNotContains('grid-field--lazy-loadable', $gridField->extraClass()); + $this->assertStringContainsString('grid-field--lazy-loaded', $gridField->extraClass()); + $this->assertStringNotContainsString('grid-field--lazy-loadable', $gridField->extraClass()); } public function testGetHTMLFragmentsNonLazy() @@ -107,8 +107,8 @@ class GridFieldLazyLoaderTest extends SapphireTest $gridField = $this->getNonLazyGridField(); $actual = $this->component->getHTMLFragments($gridField); $this->assertEmpty($actual, 'getHTMLFragments should always return an array'); - $this->assertContains('grid-field--lazy-loaded', $gridField->extraClass()); - $this->assertNotContains('grid-field--lazy-loadable', $gridField->extraClass()); + $this->assertStringContainsString('grid-field--lazy-loaded', $gridField->extraClass()); + $this->assertStringNotContainsString('grid-field--lazy-loadable', $gridField->extraClass()); } @@ -150,8 +150,8 @@ class GridFieldLazyLoaderTest extends SapphireTest $gridField = $this->makeGridFieldReadonly($this->getHeaderlessGridField()); $actual = $this->component->getHTMLFragments($gridField); $this->assertEmpty($actual, 'getHTMLFragments should always return an array'); - $this->assertContains('grid-field--lazy-loadable', $gridField->extraClass()); - $this->assertNotContains('grid-field--lazy-loaded', $gridField->extraClass()); + $this->assertStringContainsString('grid-field--lazy-loadable', $gridField->extraClass()); + $this->assertStringNotContainsString('grid-field--lazy-loaded', $gridField->extraClass()); } public function testReadOnlyGetHTMLFragmentsWithoutTabSet() @@ -159,8 +159,8 @@ class GridFieldLazyLoaderTest extends SapphireTest $gridField = $this->makeGridFieldReadonly($this->getOutOfTabSetGridField()); $actual = $this->component->getHTMLFragments($gridField); $this->assertEmpty($actual, 'getHTMLFragments should always return an array'); - $this->assertContains('grid-field--lazy-loaded', $gridField->extraClass()); - $this->assertNotContains('grid-field--lazy-loadable', $gridField->extraClass()); + $this->assertStringContainsString('grid-field--lazy-loaded', $gridField->extraClass()); + $this->assertStringNotContainsString('grid-field--lazy-loadable', $gridField->extraClass()); } public function testReadOnlyGetHTMLFragmentsNonLazy() @@ -168,8 +168,8 @@ class GridFieldLazyLoaderTest extends SapphireTest $gridField = $this->makeGridFieldReadonly($this->getNonLazyGridField()); $actual = $this->component->getHTMLFragments($gridField); $this->assertEmpty($actual, 'getHTMLFragments should always return an array'); - $this->assertContains('grid-field--lazy-loaded', $gridField->extraClass()); - $this->assertNotContains('grid-field--lazy-loadable', $gridField->extraClass()); + $this->assertStringContainsString('grid-field--lazy-loaded', $gridField->extraClass()); + $this->assertStringNotContainsString('grid-field--lazy-loadable', $gridField->extraClass()); } /** diff --git a/tests/php/Forms/GridField/GridFieldPaginatorTest.php b/tests/php/Forms/GridField/GridFieldPaginatorTest.php index f892d421d..4504143c6 100644 --- a/tests/php/Forms/GridField/GridFieldPaginatorTest.php +++ b/tests/php/Forms/GridField/GridFieldPaginatorTest.php @@ -49,7 +49,7 @@ class GridFieldPaginatorTest extends FunctionalTest Cheerleader::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->list = new DataList(Team::class); diff --git a/tests/php/Forms/GridField/GridFieldPrintButtonTest.php b/tests/php/Forms/GridField/GridFieldPrintButtonTest.php index d428a80d3..59e73a494 100644 --- a/tests/php/Forms/GridField/GridFieldPrintButtonTest.php +++ b/tests/php/Forms/GridField/GridFieldPrintButtonTest.php @@ -19,7 +19,7 @@ class GridFieldPrintButtonTest extends SapphireTest TestObject::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Forms/GridField/GridFieldSortableHeaderTest.php b/tests/php/Forms/GridField/GridFieldSortableHeaderTest.php index 3b58d0797..5973f1589 100644 --- a/tests/php/Forms/GridField/GridFieldSortableHeaderTest.php +++ b/tests/php/Forms/GridField/GridFieldSortableHeaderTest.php @@ -47,23 +47,23 @@ class GridFieldSortableHeaderTest extends SapphireTest $htmlFragment = $compontent->getHTMLFragments($gridField); // Check that the output shows name and hat as sortable fields, but not city - $this->assertContains('City', $htmlFragment['header']); - $this->assertContains( + $this->assertStringContainsString('City', $htmlFragment['header']); + $this->assertStringContainsString( 'value="Name" class="action grid-field__sort" id="action_SetOrderName"', $htmlFragment['header'] ); - $this->assertContains( + $this->assertStringContainsString( 'value="Cheerleader Hat" class="action grid-field__sort" id="action_SetOrderCheerleader-Hat-Colour"', $htmlFragment['header'] ); // Check inverse of above - $this->assertNotContains( + $this->assertStringNotContainsString( 'value="City" class="action grid-field__sort" id="action_SetOrderCity"', $htmlFragment['header'] ); - $this->assertNotContains('Name', $htmlFragment['header']); - $this->assertNotContains('Cheerleader Hat', $htmlFragment['header']); + $this->assertStringNotContainsString('Name', $htmlFragment['header']); + $this->assertStringNotContainsString('Cheerleader Hat', $htmlFragment['header']); } public function testGetManipulatedData() @@ -145,20 +145,20 @@ class GridFieldSortableHeaderTest extends SapphireTest $relationListAsql = Convert::nl2os($relationListA->sql(), ' '); // Assert that all tables are joined properly - $this->assertContains('FROM "GridFieldSortableHeaderTest_Team"', $relationListAsql); - $this->assertContains( + $this->assertStringContainsString('FROM "GridFieldSortableHeaderTest_Team"', $relationListAsql); + $this->assertStringContainsString( 'LEFT JOIN "GridFieldSortableHeaderTest_TeamGroup" ' . 'ON "GridFieldSortableHeaderTest_TeamGroup"."ID" = "GridFieldSortableHeaderTest_Team"."ID"', $relationListAsql ); - $this->assertContains( + $this->assertStringContainsString( 'LEFT JOIN "GridFieldSortableHeaderTest_Cheerleader" ' . 'AS "cheerleader_GridFieldSortableHeaderTest_Cheerleader" ' . 'ON "cheerleader_GridFieldSortableHeaderTest_Cheerleader"."ID" = ' . '"GridFieldSortableHeaderTest_Team"."CheerleaderID"', $relationListAsql ); - $this->assertContains( + $this->assertStringContainsString( 'LEFT JOIN "GridFieldSortableHeaderTest_CheerleaderHat" ' . 'AS "cheerleader_hat_GridFieldSortableHeaderTest_CheerleaderHat" ' . 'ON "cheerleader_hat_GridFieldSortableHeaderTest_CheerleaderHat"."ID" = ' @@ -185,15 +185,15 @@ class GridFieldSortableHeaderTest extends SapphireTest $relationListBsql = $relationListB->sql(); // Assert that subclasses are included in the query - $this->assertContains('FROM "GridFieldSortableHeaderTest_Team"', $relationListBsql); - $this->assertContains( + $this->assertStringContainsString('FROM "GridFieldSortableHeaderTest_Team"', $relationListBsql); + $this->assertStringContainsString( 'LEFT JOIN "GridFieldSortableHeaderTest_TeamGroup" ' . 'ON "GridFieldSortableHeaderTest_TeamGroup"."ID" = "GridFieldSortableHeaderTest_Team"."ID"', $relationListBsql ); // Joined tables are joined basetable first // Note: CheerLeader is base of Mom table, hence the alias - $this->assertContains( + $this->assertStringContainsString( 'LEFT JOIN "GridFieldSortableHeaderTest_Cheerleader" ' . 'AS "cheerleadersmom_GridFieldSortableHeaderTest_Cheerleader" ' . 'ON "cheerleadersmom_GridFieldSortableHeaderTest_Cheerleader"."ID" = ' @@ -201,14 +201,14 @@ class GridFieldSortableHeaderTest extends SapphireTest $relationListBsql ); // Then the basetable of the joined record is joined to the specific subtable - $this->assertContains( + $this->assertStringContainsString( 'LEFT JOIN "GridFieldSortableHeaderTest_Mom" ' . 'AS "cheerleadersmom_GridFieldSortableHeaderTest_Mom" ' . 'ON "cheerleadersmom_GridFieldSortableHeaderTest_Cheerleader"."ID" = ' . '"cheerleadersmom_GridFieldSortableHeaderTest_Mom"."ID"', $relationListBsql ); - $this->assertContains( + $this->assertStringContainsString( 'LEFT JOIN "GridFieldSortableHeaderTest_CheerleaderHat" ' . 'AS "cheerleadersmom_hat_GridFieldSortableHeaderTest_CheerleaderHat" ' . 'ON "cheerleadersmom_hat_GridFieldSortableHeaderTest_CheerleaderHat"."ID" = ' diff --git a/tests/php/Forms/GridField/GridFieldTest.php b/tests/php/Forms/GridField/GridFieldTest.php index 8676e8790..8fadeb8f0 100644 --- a/tests/php/Forms/GridField/GridFieldTest.php +++ b/tests/php/Forms/GridField/GridFieldTest.php @@ -2,6 +2,8 @@ namespace SilverStripe\Forms\Tests\GridField; +use InvalidArgumentException; +use LogicException; use SilverStripe\Dev\CSSContentParser; use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\FieldList; @@ -138,11 +140,10 @@ class GridFieldTest extends SapphireTest /** * @covers \SilverStripe\Forms\GridField\GridField::getModelClass - * - * @expectedException \LogicException */ public function testGridFieldModelClassThrowsException() { + $this->expectException(LogicException::class); $obj = new GridField('testfield', 'testfield', ArrayList::create()); $obj->getModelClass(); } @@ -263,11 +264,10 @@ class GridFieldTest extends SapphireTest /** * @skipUpgrade * @covers \SilverStripe\Forms\GridField\GridField::getColumnContent - * - * @expectedException \InvalidArgumentException */ public function testGetColumnContentBadArguments() { + $this->expectException(InvalidArgumentException::class); $list = new ArrayList( [ new Member(["ID" => 1, "Email" => "test@example.org"]) @@ -310,11 +310,10 @@ class GridFieldTest extends SapphireTest /** * @covers \SilverStripe\Forms\GridField\GridField::getColumnAttributes - * - * @expectedException \InvalidArgumentException */ public function testGetColumnAttributesBadArguments() { + $this->expectException(\InvalidArgumentException::class); $list = new ArrayList( [ new Member(["ID" => 1, "Email" => "test@example.org"]) @@ -325,11 +324,9 @@ class GridFieldTest extends SapphireTest $obj->getColumnAttributes($list->first(), 'Non-existing'); } - /** - * @expectedException \LogicException - */ public function testGetColumnAttributesBadResponseFromComponent() { + $this->expectException(\LogicException::class); $list = new ArrayList( [ new Member(["ID" => 1, "Email" => "test@example.org"]) @@ -358,11 +355,10 @@ class GridFieldTest extends SapphireTest /** * @covers \SilverStripe\Forms\GridField\GridField::getColumnMetadata - * - * @expectedException \LogicException */ public function testGetColumnMetadataBadResponseFromComponent() { + $this->expectException(\LogicException::class); $list = new ArrayList( [ new Member(["ID" => 1, "Email" => "test@example.org"]) @@ -375,11 +371,10 @@ class GridFieldTest extends SapphireTest /** * @covers \SilverStripe\Forms\GridField\GridField::getColumnMetadata - * - * @expectedException \InvalidArgumentException */ public function testGetColumnMetadataBadArguments() { + $this->expectException(\InvalidArgumentException::class); $list = ArrayList::create(); $config = GridFieldConfig::create()->addComponent(new Component); $obj = new GridField('testfield', 'testfield', $list, $config); @@ -388,11 +383,10 @@ class GridFieldTest extends SapphireTest /** * @covers \SilverStripe\Forms\GridField\GridField::handleAction - * - * @expectedException \InvalidArgumentException */ public function testHandleActionBadArgument() { + $this->expectException(\InvalidArgumentException::class); $obj = new GridField('testfield', 'testfield'); $obj->handleAlterAction('prft', [], []); } @@ -485,7 +479,7 @@ class GridFieldTest extends SapphireTest $field = new GridField('testfield', 'testfield', ArrayList::create(), $config); $form = new Form(null, 'testform', new FieldList([$field]), new FieldList()); - $this->assertContains( + $this->assertStringContainsString( "
rightone\nrighttwo
left
", $field->FieldHolder() ); @@ -521,7 +515,7 @@ class GridFieldTest extends SapphireTest $field = new GridField('testfield', 'testfield', ArrayList::create(), $config); $form = new Form(null, 'testform', new FieldList([$field]), new FieldList()); - $this->assertContains( + $this->assertStringContainsString( "
first\nsecond
", $field->FieldHolder() ); @@ -529,11 +523,10 @@ class GridFieldTest extends SapphireTest /** * Test that circular dependencies throw an exception - * - * @expectedException \LogicException */ public function testGridFieldCustomFragmentsCircularDependencyThrowsException() { + $this->expectException(\LogicException::class); $config = GridFieldConfig::create()->addComponents( new HTMLFragments( [ @@ -654,7 +647,7 @@ class GridFieldTest extends SapphireTest // A form that fails validation should display the validation error in the FieldHolder output. $form->validationResult(); $gridfieldOutput = $gridField->FieldHolder(); - $this->assertContains('

error

', $gridfieldOutput); + $this->assertStringContainsString('

error

', $gridfieldOutput); // Clear validation error from previous assertion. $validator->removeValidation(); @@ -664,6 +657,6 @@ class GridFieldTest extends SapphireTest $form->setValidator(new RequiredFields()); $form->validationResult(); $gridfieldOutput = $gridField->FieldHolder(); - $this->assertNotContains('

', $gridfieldOutput); + $this->assertStringNotContainsString('

', $gridfieldOutput); } } diff --git a/tests/php/Forms/GroupedDropdownFieldTest.php b/tests/php/Forms/GroupedDropdownFieldTest.php index 68b4a2b72..ccd06f7f5 100644 --- a/tests/php/Forms/GroupedDropdownFieldTest.php +++ b/tests/php/Forms/GroupedDropdownFieldTest.php @@ -82,7 +82,7 @@ class GroupedDropdownFieldTest extends SapphireTest ] ); - $this->assertRegExp( + $this->assertMatchesRegularExpression( '/

Main

', $result); - $this->assertContains('

Secondary

', $result); + $this->assertStringContainsString('

Main

', $result); + $this->assertStringContainsString('

Secondary

', $result); $transformationTabSet->setTabSet($optionsTabSet); $result = $transformationTabSet->FieldHolder(); - $this->assertContains('

Options

', $result); + $this->assertStringContainsString('

Options

', $result); } } diff --git a/tests/php/Forms/SelectionGroupTest.php b/tests/php/Forms/SelectionGroupTest.php index c316b1b00..711695d5c 100644 --- a/tests/php/Forms/SelectionGroupTest.php +++ b/tests/php/Forms/SelectionGroupTest.php @@ -36,8 +36,8 @@ class SelectionGroupTest extends SapphireTest $this->assertEquals(' one title', (string)$listElOne->label[0]); $this->assertEquals(' two title', (string)$listElTwo->label[0]); - $this->assertContains('one view', (string)$listElOne->div); - $this->assertContains('two view', (string)$listElTwo->div); + $this->assertStringContainsString('one view', (string)$listElOne->div); + $this->assertStringContainsString('two view', (string)$listElTwo->div); } public function testSelectedFieldHolder() diff --git a/tests/php/Forms/TextareaFieldTest.php b/tests/php/Forms/TextareaFieldTest.php index e973857bf..accd6a587 100644 --- a/tests/php/Forms/TextareaFieldTest.php +++ b/tests/php/Forms/TextareaFieldTest.php @@ -14,12 +14,12 @@ class TextareaFieldTest extends SapphireTest $inputText = "These are some unicodes: ä, ö, & ü"; $field = new TextareaField("Test", "Test"); $field->setValue($inputText); - $this->assertContains('These are some unicodes: ä, ö, & ü', $field->Field()); + $this->assertStringContainsString('These are some unicodes: ä, ö, & ü', $field->Field()); // Test shortcodes $inputText = "Shortcode: [file_link id=4]"; $field = new TextareaField("Test", "Test"); $field->setValue($inputText); - $this->assertContains('Shortcode: [file_link id=4]', $field->Field()); + $this->assertStringContainsString('Shortcode: [file_link id=4]', $field->Field()); } /** @@ -31,7 +31,7 @@ class TextareaFieldTest extends SapphireTest $field = new TextareaField("Test", "Test"); $field->setValue($inputText); $field = $field->performReadonlyTransformation(); - $this->assertContains('These are some unicodes: äöü', $field->Field()); + $this->assertStringContainsString('These are some unicodes: äöü', $field->Field()); } /** @@ -43,7 +43,7 @@ class TextareaFieldTest extends SapphireTest $field = new TextareaField("Test", "Test"); $field = $field->performReadonlyTransformation(); $field->setValue($inputText); - $this->assertContains( + $this->assertStringContainsString( 'These are some special <html> chars including 'single' &' . ' "double" quotations', $field->Field() diff --git a/tests/php/Forms/TimeFieldReadonlyTest.php b/tests/php/Forms/TimeFieldReadonlyTest.php index f32f69d06..9b693ea53 100644 --- a/tests/php/Forms/TimeFieldReadonlyTest.php +++ b/tests/php/Forms/TimeFieldReadonlyTest.php @@ -9,22 +9,22 @@ use SilverStripe\i18n\i18n; class TimeFieldReadonlyTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); i18n::set_locale('en_NZ'); } - + public function testPerformReadonly() { $field = new TimeField('Time', 'Time', '23:00:00'); $roField = $field->performReadonlyTransformation(); $this->assertInstanceOf(TimeField_Readonly::class, $roField); - + $this->assertTrue($roField->isReadonly()); $this->assertEquals($roField->dataValue(), '23:00:00'); } - + public function testSettingsCarryOver() { $field = new TimeField('Time', 'Time'); @@ -35,7 +35,7 @@ class TimeFieldReadonlyTest extends SapphireTest ->setLocale('en_US') ->setTimeLength(IntlDateFormatter::SHORT) ->setValue('23:00:00'); - + $roField = $field->performReadonlyTransformation(); $this->assertFalse($roField->getHTML5()); $this->assertEquals($roField->getTimeFormat(), 'KK:mma'); diff --git a/tests/php/Forms/TimeFieldTest.php b/tests/php/Forms/TimeFieldTest.php index 65e40fb22..95b867870 100644 --- a/tests/php/Forms/TimeFieldTest.php +++ b/tests/php/Forms/TimeFieldTest.php @@ -3,6 +3,7 @@ namespace SilverStripe\Forms\Tests; use IntlDateFormatter; +use LogicException; use SilverStripe\Core\Config\Config; use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\TimeField; @@ -11,7 +12,7 @@ use SilverStripe\i18n\i18n; class TimeFieldTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); i18n::set_locale('en_NZ'); @@ -147,36 +148,30 @@ class TimeFieldTest extends SapphireTest $this->assertEquals($f->Value(), '23:59:00'); } - /** - * @expectedException \LogicException - * @expectedExceptionMessageRegExp /Please opt-out .* if using setTimeFormat/ - */ public function testHtml5WithCustomFormatThrowsException() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessageMatches('/Please opt-out .* if using setTimeFormat/'); $f = new TimeField('Time', 'Time'); $f->setValue('15:59:00'); $f->setTimeFormat('mm:HH'); $f->Value(); } - /** - * @expectedException \LogicException - * @expectedExceptionMessageRegExp /Please opt-out .* if using setTimeLength/ - */ public function testHtml5WithCustomDateLengthThrowsException() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessageMatches('/Please opt-out .* if using setTimeLength/'); $f = new TimeField('Time', 'Time'); $f->setValue('15:59:00'); $f->setTimeLength(IntlDateFormatter::MEDIUM); $f->Value(); } - /** - * @expectedException \LogicException - * @expectedExceptionMessageRegExp /Please opt-out .* if using setLocale/ - */ public function testHtml5WithCustomLocaleThrowsException() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessageMatches('/Please opt-out .* if using setLocale/'); $f = new TimeField('Time', 'Time'); $f->setValue('15:59:00'); $f->setLocale('de_DE'); diff --git a/tests/php/Forms/TipTest.php b/tests/php/Forms/TipTest.php index 02ea1a9ad..b815b9746 100644 --- a/tests/php/Forms/TipTest.php +++ b/tests/php/Forms/TipTest.php @@ -52,23 +52,21 @@ class TipTest extends SapphireTest /** * Ensure passing an invalid importance level to the constructor fails - * - * @expectedException InvalidArgumentException - * @expectedExceptionMessage Provided importance level must be defined in Tip::IMPORTANCE_LEVELS */ public function testInvalidImportanceLevelInConstructorCausesException() { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Provided importance level must be defined in Tip::IMPORTANCE_LEVELS'); $tip = new Tip('message', 'arbitrary-importance'); } /** * Ensure setting an invalid importance level fails - * - * @expectedException InvalidArgumentException - * @expectedExceptionMessage Provided importance level must be defined in Tip::IMPORTANCE_LEVELS */ public function testInvalidImportanceLevelInSetterCausesException() { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Provided importance level must be defined in Tip::IMPORTANCE_LEVELS'); $tip = new Tip('message'); $tip->setImportanceLevel('arbitrary-importance'); diff --git a/tests/php/Forms/TreeDropdownFieldTest.php b/tests/php/Forms/TreeDropdownFieldTest.php index 3d78c7ab3..88ffedb4d 100644 --- a/tests/php/Forms/TreeDropdownFieldTest.php +++ b/tests/php/Forms/TreeDropdownFieldTest.php @@ -308,11 +308,11 @@ class TreeDropdownFieldTest extends SapphireTest $field->setValue($fileMock->ID); $readonlyField = $field->performReadonlyTransformation(); $result = (string) $readonlyField->Field(); - $this->assertContains( + $this->assertStringContainsString( '<Special & characters>', $result ); - $this->assertContains( + $this->assertStringContainsString( '', $result ); diff --git a/tests/php/Forms/TreeMultiselectFieldTest.php b/tests/php/Forms/TreeMultiselectFieldTest.php index c0d7ea2e9..f004aea5e 100644 --- a/tests/php/Forms/TreeMultiselectFieldTest.php +++ b/tests/php/Forms/TreeMultiselectFieldTest.php @@ -2,6 +2,7 @@ namespace SilverStripe\Forms\Tests; +use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts; use SilverStripe\Assets\File; use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\Form; @@ -12,6 +13,8 @@ use SilverStripe\View\SSViewer; class TreeMultiselectFieldTest extends SapphireTest { + use ArraySubsetAsserts; + protected static $fixture_file = 'TreeDropdownFieldTest.yml'; protected static $extra_dataobjects = [ @@ -56,7 +59,7 @@ class TreeMultiselectFieldTest extends SapphireTest */ protected $fieldValue; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -170,8 +173,8 @@ class TreeMultiselectFieldTest extends SapphireTest $this->assertCount(0, $items, 'there must be no items selected'); $html = $field->Field(); - $this->assertContains($field->ID(), $html); - $this->assertContains('unchanged', $html); + $this->assertStringContainsString($field->ID(), $html); + $this->assertStringContainsString('unchanged', $html); } @@ -199,8 +202,8 @@ class TreeMultiselectFieldTest extends SapphireTest $this->assertCount(2, $items, 'there must be exactly 2 items selected'); $html = $field->Field(); - $this->assertContains($field->ID(), $html); - $this->assertContains($this->fieldValue, $html); + $this->assertStringContainsString($field->ID(), $html); + $this->assertStringContainsString($this->fieldValue, $html); } /** @@ -248,7 +251,7 @@ class TreeMultiselectFieldTest extends SapphireTest $this->assertCount(0, $items, 'there must be 0 selected items'); $html = $field->Field(); - $this->assertContains($field->ID(), $html); + $this->assertStringContainsString($field->ID(), $html); } /** @@ -298,8 +301,8 @@ class TreeMultiselectFieldTest extends SapphireTest $this->assertCount(2, $items, 'there must be exactly 2 selected items'); $html = $field->Field(); - $this->assertContains($field->ID(), $html); - $this->assertContains($this->fieldValue, $html); + $this->assertStringContainsString($field->ID(), $html); + $this->assertStringContainsString($this->fieldValue, $html); } public function testGetItems() diff --git a/tests/php/Logging/DebugViewFriendlyErrorFormatterTest.php b/tests/php/Logging/DebugViewFriendlyErrorFormatterTest.php index f1d9e0ed9..2a730e56b 100644 --- a/tests/php/Logging/DebugViewFriendlyErrorFormatterTest.php +++ b/tests/php/Logging/DebugViewFriendlyErrorFormatterTest.php @@ -2,7 +2,7 @@ namespace SilverStripe\Logging\Tests; -use PHPUnit_Framework_MockObject_MockObject; +use PHPUnit\Framework\MockObject\MockObject; use SilverStripe\Control\Email\Email; use SilverStripe\Control\HTTPRequest; use SilverStripe\Core\Injector\Injector; @@ -11,7 +11,7 @@ use SilverStripe\Logging\DebugViewFriendlyErrorFormatter; class DebugViewFriendlyErrorFormatterTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); Email::config()->set('admin_email', 'testy@mctest.face'); @@ -19,7 +19,7 @@ class DebugViewFriendlyErrorFormatterTest extends SapphireTest public function testFormatPassesRecordCodeToOutput() { - /** @var DebugViewFriendlyErrorFormatter|PHPUnit_Framework_MockObject_MockObject $mock */ + /** @var DebugViewFriendlyErrorFormatter|MockObject $mock */ $mock = $this->getMockBuilder(DebugViewFriendlyErrorFormatter::class) ->setMethods(['output']) ->getMock(); @@ -30,7 +30,7 @@ class DebugViewFriendlyErrorFormatterTest extends SapphireTest public function testFormatPassesInstanceStatusCodeToOutputWhenNotProvidedByRecord() { - /** @var DebugViewFriendlyErrorFormatter|PHPUnit_Framework_MockObject_MockObject $mock */ + /** @var DebugViewFriendlyErrorFormatter|MockObject $mock */ $mock = $this->getMockBuilder(DebugViewFriendlyErrorFormatter::class) ->setMethods(['output']) ->getMock(); @@ -49,7 +49,7 @@ class DebugViewFriendlyErrorFormatterTest extends SapphireTest ['horse' => 'caballo'], ]; - /** @var DebugViewFriendlyErrorFormatter|PHPUnit_Framework_MockObject_MockObject $mock */ + /** @var DebugViewFriendlyErrorFormatter|MockObject $mock */ $mock = $this->getMockBuilder(DebugViewFriendlyErrorFormatter::class) ->setMethods(['format']) ->getMock(); diff --git a/tests/php/Logging/DetailedErrorFormatterTest.php b/tests/php/Logging/DetailedErrorFormatterTest.php index b36786f81..21b34a735 100644 --- a/tests/php/Logging/DetailedErrorFormatterTest.php +++ b/tests/php/Logging/DetailedErrorFormatterTest.php @@ -19,10 +19,10 @@ class DetailedErrorFormatterTest extends SapphireTest ]]); $base = __DIR__; - $this->assertContains('ERROR [Emergency]: Uncaught Exception: Error', $output); - $this->assertContains("Line 32 in $base/DetailedErrorFormatterTest/ErrorGenerator.php", $output); - $this->assertContains('* 32: throw new Exception(\'Error\');', $output); - $this->assertContains( + $this->assertStringContainsString('ERROR [Emergency]: Uncaught Exception: Error', $output); + $this->assertStringContainsString("Line 32 in $base/DetailedErrorFormatterTest/ErrorGenerator.php", $output); + $this->assertStringContainsString('* 32: throw new Exception(\'Error\');', $output); + $this->assertStringContainsString( 'SilverStripe\\Logging\\Tests\\DetailedErrorFormatterTest\\ErrorGenerator->mockException(4)', $output ); @@ -40,10 +40,10 @@ class DetailedErrorFormatterTest extends SapphireTest $formatter = new DetailedErrorFormatter(); $result = $formatter->format($record); - $this->assertContains('ERRNO 401', $result, 'Status code was not found in trace'); - $this->assertContains('Denied', $result, 'Message was not found in trace'); - $this->assertContains('Line 4 in index.php', $result, 'Line or filename were not found in trace'); - $this->assertContains(self::class, $result, 'Backtrace doesn\'t show current test class'); + $this->assertStringContainsString('ERRNO 401', $result, 'Status code was not found in trace'); + $this->assertStringContainsString('Denied', $result, 'Message was not found in trace'); + $this->assertStringContainsString('Line 4 in index.php', $result, 'Line or filename were not found in trace'); + $this->assertStringContainsString(self::class, $result, 'Backtrace doesn\'t show current test class'); } public function testFormatBatch() @@ -66,9 +66,9 @@ class DetailedErrorFormatterTest extends SapphireTest $formatter = new DetailedErrorFormatter(); $result = $formatter->formatBatch($records); - $this->assertContains('ERRNO 401', $result, 'First status code was not found in trace'); - $this->assertContains('ERRNO 404', $result, 'Second status code was not found in trace'); - $this->assertContains('Denied', $result, 'First message was not found in trace'); - $this->assertContains('Not found', $result, 'Second message was not found in trace'); + $this->assertStringContainsString('ERRNO 401', $result, 'First status code was not found in trace'); + $this->assertStringContainsString('ERRNO 404', $result, 'Second status code was not found in trace'); + $this->assertStringContainsString('Denied', $result, 'First message was not found in trace'); + $this->assertStringContainsString('Not found', $result, 'Second message was not found in trace'); } } diff --git a/tests/php/Logging/HTTPOutputHandlerTest.php b/tests/php/Logging/HTTPOutputHandlerTest.php index 198361bf5..4dfa8009d 100644 --- a/tests/php/Logging/HTTPOutputHandlerTest.php +++ b/tests/php/Logging/HTTPOutputHandlerTest.php @@ -12,7 +12,7 @@ use SilverStripe\Logging\HTTPOutputHandler; class HTTPOutputHandlerTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Logging/MonologErrorHandlerTest.php b/tests/php/Logging/MonologErrorHandlerTest.php index 0cd051160..6bbe37b03 100644 --- a/tests/php/Logging/MonologErrorHandlerTest.php +++ b/tests/php/Logging/MonologErrorHandlerTest.php @@ -2,18 +2,17 @@ namespace SilverStripe\Logging\Tests; +use InvalidArgumentException; use Psr\Log\LoggerInterface; use SilverStripe\Dev\SapphireTest; use SilverStripe\Logging\MonologErrorHandler; class MonologErrorHandlerTest extends SapphireTest { - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessageRegExp /No Logger properties passed to MonologErrorHandler/ - */ public function testStartThrowsExceptionWithoutLoggerDefined() { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessageMatches('/No Logger properties passed to MonologErrorHandler/'); $handler = new MonologErrorHandler(); $handler->start(); } diff --git a/tests/php/ORM/ArrayListTest.php b/tests/php/ORM/ArrayListTest.php index c6a586248..5f4537a40 100644 --- a/tests/php/ORM/ArrayListTest.php +++ b/tests/php/ORM/ArrayListTest.php @@ -133,19 +133,6 @@ class ArrayListTest extends SapphireTest ); } - /** - * @expectedException PHPUnit_Framework_Error - */ - public function testZeroLimit() - { - Deprecation::notification_version('4.3.0'); - $list = new ArrayList([ - ['Key' => 1], - ['Key' => 2], - ]); - $list->limit(0); - } - public function testAddRemove() { $list = new ArrayList( @@ -737,6 +724,7 @@ class ArrayListTest extends SapphireTest // This call will trigger a fatal error if there are issues with circular dependencies $items->sort('Sort'); + $this->assertTrue(true, 'Sort with circular dependencies does not trigger an error.'); } /** diff --git a/tests/php/ORM/DBDateTest.php b/tests/php/ORM/DBDateTest.php index 6f917b866..6043c76be 100644 --- a/tests/php/ORM/DBDateTest.php +++ b/tests/php/ORM/DBDateTest.php @@ -2,6 +2,8 @@ namespace SilverStripe\ORM\Tests; +use InvalidArgumentException; +use PHPUnit\Framework\Error\Notice; use SilverStripe\Dev\SapphireTest; use SilverStripe\i18n\i18n; use SilverStripe\ORM\FieldType\DBDate; @@ -15,7 +17,7 @@ class DBDateTest extends SapphireTest { protected $oldError = null; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->oldError = error_reporting(); @@ -24,7 +26,7 @@ class DBDateTest extends SapphireTest i18n::set_locale('en_NZ'); } - protected function tearDown() + protected function tearDown(): void { $this->restoreNotices(); parent::tearDown(); @@ -36,7 +38,6 @@ class DBDateTest extends SapphireTest protected function suppressNotices() { error_reporting(error_reporting() & ~E_USER_NOTICE); - \PHPUnit_Framework_Error_Notice::$enabled = false; } /** @@ -45,7 +46,6 @@ class DBDateTest extends SapphireTest protected function restoreNotices() { error_reporting($this->oldError); - \PHPUnit_Framework_Error_Notice::$enabled = true; } public function testNiceDate() @@ -92,21 +92,17 @@ class DBDateTest extends SapphireTest ); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Invalid date: '3/16/2003'. Use y-MM-dd to prevent this error. - */ public function testMDYConversion() { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("Invalid date: '3/16/2003'. Use y-MM-dd to prevent this error."); DBField::create_field('Date', '3/16/2003'); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Invalid date: '03-03-04'. Use y-MM-dd to prevent this error. - */ public function testY2kCorrection() { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("Invalid date: '03-03-04'. Use y-MM-dd to prevent this error."); DBField::create_field('Date', '03-03-04'); } diff --git a/tests/php/ORM/DBDatetimeTest.php b/tests/php/ORM/DBDatetimeTest.php index aa0a09b26..6abf14d4e 100644 --- a/tests/php/ORM/DBDatetimeTest.php +++ b/tests/php/ORM/DBDatetimeTest.php @@ -11,7 +11,7 @@ use SilverStripe\ORM\FieldType\DBDatetime; */ class DBDatetimeTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); i18n::set_locale('en_NZ'); @@ -108,10 +108,10 @@ class DBDatetimeTest extends SapphireTest // note: Some localisation packages exclude the ',' in default medium format i18n::set_locale('en_NZ'); - $this->assertRegExp('#11/12/2001(,)? 10:10 PM#i', $date->Nice()); + $this->assertMatchesRegularExpression('#11/12/2001(,)? 10:10 PM#i', $date->Nice()); i18n::set_locale('en_US'); - $this->assertRegExp('#Dec 11(,)? 2001(,)? 10:10 PM#i', $date->Nice()); + $this->assertMatchesRegularExpression('#Dec 11(,)? 2001(,)? 10:10 PM#i', $date->Nice()); } public function testDate() @@ -123,7 +123,7 @@ class DBDatetimeTest extends SapphireTest public function testTime() { $date = DBDatetime::create_field('Datetime', '2001-12-31 22:10:59'); - $this->assertRegexp('#10:10:59 PM#i', $date->Time()); + $this->assertMatchesRegularExpression('#10:10:59 PM#i', $date->Time()); } public function testTime24() diff --git a/tests/php/ORM/DBHTMLTextTest.php b/tests/php/ORM/DBHTMLTextTest.php index 3a54c5b0c..4390fb400 100644 --- a/tests/php/ORM/DBHTMLTextTest.php +++ b/tests/php/ORM/DBHTMLTextTest.php @@ -17,7 +17,7 @@ class DBHTMLTextTest extends SapphireTest private $previousLocaleSetting = null; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -30,7 +30,7 @@ class DBHTMLTextTest extends SapphireTest ShortcodeParser::set_active('htmltest'); } - protected function tearDown() + protected function tearDown(): void { // If a test sets the locale, reset it on teardown diff --git a/tests/php/ORM/DBTextTest.php b/tests/php/ORM/DBTextTest.php index 65c82541f..7a2a1888e 100644 --- a/tests/php/ORM/DBTextTest.php +++ b/tests/php/ORM/DBTextTest.php @@ -14,14 +14,14 @@ class DBTextTest extends SapphireTest private $previousLocaleSetting = null; - public function setUp() + protected function setUp(): void { parent::setUp(); // clear the previous locale setting $this->previousLocaleSetting = null; } - public function tearDown() + protected function tearDown(): void { parent::tearDown(); // If a test sets the locale, reset it on teardown diff --git a/tests/php/ORM/DBTimeTest.php b/tests/php/ORM/DBTimeTest.php index 80c2f8029..fa2420c5f 100644 --- a/tests/php/ORM/DBTimeTest.php +++ b/tests/php/ORM/DBTimeTest.php @@ -10,7 +10,7 @@ use SilverStripe\Security\Member; class DBTimeTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); i18n::set_locale('en_NZ'); @@ -48,12 +48,12 @@ class DBTimeTest extends SapphireTest public function testNice() { $time = DBTime::create_field('Time', '17:15:55'); - $this->assertRegexp('#5:15:55 PM#i', $time->Nice()); + $this->assertMatchesRegularExpression('#5:15:55 PM#i', $time->Nice()); } public function testShort() { $time = DBTime::create_field('Time', '17:15:55'); - $this->assertRegexp('#5:15 PM#i', $time->Short()); + $this->assertMatchesRegularExpression('#5:15 PM#i', $time->Short()); } } diff --git a/tests/php/ORM/DataListTest.php b/tests/php/ORM/DataListTest.php index 22e1cc513..b5d117510 100755 --- a/tests/php/ORM/DataListTest.php +++ b/tests/php/ORM/DataListTest.php @@ -92,11 +92,9 @@ class DataListTest extends SapphireTest $this->assertEquals(2, $newList->Count(), 'List should only contain two objects after subtraction'); } - /** - * @expectedException \InvalidArgumentException - */ public function testSubtractBadDataclassThrowsException() { + $this->expectException(InvalidArgumentException::class); $teamsComments = TeamComment::get(); $teams = Team::get(); $teamsComments->subtract($teams); @@ -155,13 +153,13 @@ class DataListTest extends SapphireTest public function testDistinct() { $list = TeamComment::get(); - $this->assertContains('SELECT DISTINCT', $list->dataQuery()->sql($params), 'Query is set as distinct by default'); + $this->assertStringContainsString('SELECT DISTINCT', $list->dataQuery()->sql($params), 'Query is set as distinct by default'); $list = $list->distinct(false); - $this->assertNotContains('SELECT DISTINCT', $list->dataQuery()->sql($params), 'Query does not contain distinct'); + $this->assertStringNotContainsString('SELECT DISTINCT', $list->dataQuery()->sql($params), 'Query does not contain distinct'); $list = $list->distinct(true); - $this->assertContains('SELECT DISTINCT', $list->dataQuery()->sql($params), 'Query contains distinct'); + $this->assertStringContainsString('SELECT DISTINCT', $list->dataQuery()->sql($params), 'Query contains distinct'); } public function testDataClass() @@ -432,8 +430,8 @@ class DataListTest extends SapphireTest // Assert that filtering on ID searches by the base table, not the child table field $query = SubTeam::get()->filter('ID', 4)->sql($parameters); - $this->assertContains('WHERE ("DataObjectTest_Team"."ID" = ?)', $query); - $this->assertNotContains('WHERE ("DataObjectTest_SubTeam"."ID" = ?)', $query); + $this->assertStringContainsString('WHERE ("DataObjectTest_Team"."ID" = ?)', $query); + $this->assertStringNotContainsString('WHERE ("DataObjectTest_SubTeam"."ID" = ?)', $query); } public function testByIDs() @@ -585,12 +583,10 @@ class DataListTest extends SapphireTest $this->assertEquals('Phil', $list->last()->Name); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Fans is not a linear relation on model SilverStripe\ORM\Tests\DataObjectTest\Player - */ public function testSortInvalidParameters() { + $this->expectException(InvalidArgumentException::class); + $this->expectDeprecationMessage('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 } @@ -756,7 +752,7 @@ class DataListTest extends SapphireTest public function testSimpleFilterWithNonExistingComparisator() { $this->expectException(InjectorNotFoundException::class); - $this->expectExceptionMessageRegExp('/Class "?DataListFilter.Bogus"? does not exist/'); + $this->expectExceptionMessageMatches('/Class "?DataListFilter.Bogus"? does not exist/'); $list = TeamComment::get(); $list->filter('Comment:Bogus', 'team comment'); @@ -768,7 +764,7 @@ class DataListTest extends SapphireTest public function testInvalidModifier() { $this->expectException(InjectorNotFoundException::class); - $this->expectExceptionMessageRegExp('/Class "?DataListFilter.invalidmodifier"? does not exist/'); + $this->expectExceptionMessageMatches('/Class "?DataListFilter.invalidmodifier"? does not exist/'); $list = TeamComment::get(); $list->filter('Comment:invalidmodifier', 'team comment'); @@ -1093,12 +1089,10 @@ class DataListTest extends SapphireTest $this->assertEquals('007', $list->first()->ShirtNumber); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage MascotAnimal is not a relation on model SilverStripe\ORM\Tests\DataObjectTest\Team - */ public function testFilterOnInvalidRelation() { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('MascotAnimal is not a relation on model SilverStripe\ORM\Tests\DataObjectTest\Team'); // Filter on missing relation 'MascotAnimal' Team::get() ->filter('MascotAnimal.Name', 'Richard') @@ -1351,7 +1345,7 @@ class DataListTest extends SapphireTest $ex = $e; } $this->assertInstanceOf(\InvalidArgumentException::class, $ex); - $this->assertRegExp('/Malformed/', $ex->getMessage()); + $this->assertMatchesRegularExpression('/Malformed/', $ex->getMessage()); $filter = new ExactMatchFilter('Comments.Max(NonExistentColumn)'); @@ -1363,7 +1357,7 @@ class DataListTest extends SapphireTest $ex = $e; } $this->assertInstanceOf(\InvalidArgumentException::class, $ex); - $this->assertRegExp('/Invalid column/', $ex->getMessage()); + $this->assertMatchesRegularExpression('/Invalid column/', $ex->getMessage()); } public function testAggregateFilters() @@ -1699,14 +1693,10 @@ class DataListTest extends SapphireTest $this->assertListEquals([['Name' => 'Joe']], $list); } - /** - * Test exact match filter with empty array items - * - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Cannot filter "DataObjectTest_TeamComment"."Name" against an empty set - */ public function testEmptyFilter() { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Cannot filter "DataObjectTest_TeamComment"."Name" against an empty set'); $list = TeamComment::get(); $list->exclude('Name', []); } diff --git a/tests/php/ORM/DataObjectSchemaGenerationTest.php b/tests/php/ORM/DataObjectSchemaGenerationTest.php index e3d583d87..5822f0c76 100644 --- a/tests/php/ORM/DataObjectSchemaGenerationTest.php +++ b/tests/php/ORM/DataObjectSchemaGenerationTest.php @@ -20,7 +20,7 @@ class DataObjectSchemaGenerationTest extends SapphireTest SortedObject::class, ]; - public static function setUpBeforeClass() + public static function setUpBeforeClass(): void { // Start tests static::start(); diff --git a/tests/php/ORM/DataObjectTest.php b/tests/php/ORM/DataObjectTest.php index 3c243b845..8948a9104 100644 --- a/tests/php/ORM/DataObjectTest.php +++ b/tests/php/ORM/DataObjectTest.php @@ -21,6 +21,7 @@ use SilverStripe\ORM\Tests\DataObjectTest\Company; use SilverStripe\ORM\Tests\DataObjectTest\Player; use SilverStripe\ORM\Tests\DataObjectTest\Team; use SilverStripe\ORM\Tests\DataObjectTest\TreeNode; +use SilverStripe\ORM\ValidationException; use SilverStripe\Security\Member; use SilverStripe\View\ViewableData; use stdClass; @@ -64,7 +65,7 @@ class DataObjectTest extends SapphireTest DataObjectTest\TreeNode::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -1483,12 +1484,9 @@ class DataObjectTest extends SapphireTest $this->assertEquals('New and improved team 1', $reloadedTeam1->Title); } - - /** - * @expectedException \SilverStripe\ORM\ValidationException - */ public function testWritingInvalidDataObjectThrowsException() { + $this->expectException(ValidationException::class); $validatedObject = new DataObjectTest\ValidatedObject(); $validatedObject->write(); } @@ -1638,29 +1636,23 @@ class DataObjectTest extends SapphireTest $this->assertEquals('Staff', $ceoObj->EmploymentType); } - /** - * @expectedException \InvalidArgumentException - */ public function testValidateModelDefinitionsFailsWithArray() { + $this->expectException(\InvalidArgumentException::class); Config::modify()->merge(DataObjectTest\Team::class, 'has_one', ['NotValid' => ['NoArraysAllowed']]); DataObject::getSchema()->hasOneComponent(DataObjectTest\Team::class, 'NotValid'); } - /** - * @expectedException \InvalidArgumentException - */ public function testValidateModelDefinitionsFailsWithIntKey() { + $this->expectException(\InvalidArgumentException::class); Config::modify()->set(DataObjectTest\Team::class, 'has_many', [0 => DataObjectTest\Player::class]); DataObject::getSchema()->hasManyComponent(DataObjectTest\Team::class, 0); } - /** - * @expectedException \InvalidArgumentException - */ public function testValidateModelDefinitionsFailsWithIntValue() { + $this->expectException(\InvalidArgumentException::class); Config::modify()->merge(DataObjectTest\Team::class, 'many_many', ['Players' => 12]); DataObject::getSchema()->manyManyComponent(DataObjectTest\Team::class, 'Players'); } @@ -1687,7 +1679,7 @@ class DataObjectTest extends SapphireTest $this->assertEquals($changedDO->ClassName, DataObjectTest\SubTeam::class); // Test invalid classes fail - $this->expectException(InvalidArgumentException::class); + $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('Controller is not a valid subclass of DataObject'); /** * @skipUpgrade @@ -2007,7 +1999,7 @@ class DataObjectTest extends SapphireTest $obj = new DataObjectTest\Fixture(); $obj->write(); - $this->assertInternalType("int", $obj->ID); + $this->assertIsInt($obj->ID); } /** @@ -2287,11 +2279,9 @@ class DataObjectTest extends SapphireTest ); } - /** - * @expectedException LogicException - */ public function testInvalidate() { + $this->expectException(\LogicException::class); $do = new DataObjectTest\Fixture(); $do->write(); @@ -2382,7 +2372,7 @@ class DataObjectTest extends SapphireTest $this->assertEquals("PHIL IS A UNIQUE GUY, AND COMMENTS ON TEAM2", $comment->relField('Comment.UpperCase')); // relField throws exception on invalid properties - $this->expectException(LogicException::class); + $this->expectException(\LogicException::class); $this->expectExceptionMessage("Not is not a relation/field on " . DataObjectTest\TeamComment::class); $comment->relField('Not.A.Field'); } @@ -2410,7 +2400,7 @@ class DataObjectTest extends SapphireTest $this->assertEquals("Team 1", $player->relObject('Teams.First.Title')->getValue()); // relObject throws exception on invalid properties - $this->expectException(LogicException::class); + $this->expectException(\LogicException::class); $this->expectExceptionMessage("Not is not a relation/field on " . DataObjectTest\Player::class); $player->relObject('Not.A.Field'); } @@ -2422,16 +2412,14 @@ class DataObjectTest extends SapphireTest $this->assertInstanceOf(DataObjectTest\Player::class, DataObjectTest\Player::get()->first()); // You can't pass arguments to LSB syntax - use the DataList methods instead. - $this->expectException(InvalidArgumentException::class); + $this->expectException(\InvalidArgumentException::class); DataObjectTest\Player::get(null, "\"ID\" = 1"); } - /** - * @expectedException \InvalidArgumentException - */ public function testBrokenLateStaticBindingStyle() { + $this->expectException(\InvalidArgumentException::class); // If you call DataObject::get() you have to pass a first argument DataObject::get(); } @@ -2456,7 +2444,7 @@ class DataObjectTest extends SapphireTest public function testSetFieldWithArrayOnScalarOnlyField() { - $this->expectException(InvalidArgumentException::class); + $this->expectException(\InvalidArgumentException::class); $do = Company::singleton(); $do->FoundationYear = '1984'; $do->FoundationYear = ['Amount' => 123, 'Currency' => 'CAD']; @@ -2488,7 +2476,7 @@ class DataObjectTest extends SapphireTest public function testWriteManipulationWithNonScalarValuesDisallowed() { - $this->expectException(InvalidArgumentException::class); + $this->expectException(\InvalidArgumentException::class); $do = DataObjectTest\MockDynamicAssignmentDataObject::create(); $do->write(); diff --git a/tests/php/ORM/DataObjectTest.yml b/tests/php/ORM/DataObjectTest.yml index b55c6811a..aa71fc3e8 100644 --- a/tests/php/ORM/DataObjectTest.yml +++ b/tests/php/ORM/DataObjectTest.yml @@ -49,7 +49,7 @@ SilverStripe\ORM\Tests\DataObjectTest\Player: captain1: FirstName: Captain Surname: Zookeeper - ShirtNumber: 007 + ShirtNumber: '007' FavouriteTeam: =>SilverStripe\ORM\Tests\DataObjectTest\Team.team1 Teams: =>SilverStripe\ORM\Tests\DataObjectTest\Team.team1 FoundingTeams: =>SilverStripe\ORM\Tests\DataObjectTest\Team.team1 diff --git a/tests/php/ORM/DataQueryTest.php b/tests/php/ORM/DataQueryTest.php index 9f7476376..f79da3f8c 100644 --- a/tests/php/ORM/DataQueryTest.php +++ b/tests/php/ORM/DataQueryTest.php @@ -79,12 +79,12 @@ class DataQueryTest extends SapphireTest $dq = new DataQuery(DataQueryTest\ObjectB::class); $dq->applyRelation('TestC'); $this->assertTrue($dq->query()->isJoinedTo('testc_DataQueryTest_C')); - $this->assertContains('"testc_DataQueryTest_C"."ID" = "DataQueryTest_B"."TestCID"', $dq->sql()); + $this->assertStringContainsString('"testc_DataQueryTest_C"."ID" = "DataQueryTest_B"."TestCID"', $dq->sql()); $dq = new DataQuery(DataQueryTest\ObjectB::class); $dq->applyRelation('TestCTwo'); $this->assertTrue($dq->query()->isJoinedTo('testctwo_DataQueryTest_C')); - $this->assertContains('"testctwo_DataQueryTest_C"."ID" = "DataQueryTest_B"."TestCTwoID"', $dq->sql()); + $this->assertStringContainsString('"testctwo_DataQueryTest_C"."ID" = "DataQueryTest_B"."TestCTwoID"', $dq->sql()); } public function testApplyRelationDeepInheritance() @@ -94,7 +94,7 @@ class DataQueryTest extends SapphireTest //apply a relation to a relation from an ancestor class $newDQ->applyRelation('TestA'); $this->assertTrue($newDQ->query()->isJoinedTo('DataQueryTest_C')); - $this->assertContains('"testa_DataQueryTest_A"."ID" = "DataQueryTest_C"."TestAID"', $newDQ->sql($params)); + $this->assertStringContainsString('"testa_DataQueryTest_A"."ID" = "DataQueryTest_C"."TestAID"', $newDQ->sql($params)); //test many_many relation @@ -105,7 +105,7 @@ class DataQueryTest extends SapphireTest //check we are "joined" to the DataObject's table (there is no distinction between FROM or JOIN clauses) $this->assertTrue($newDQ->query()->isJoinedTo($baseDBTable)); //check we are explicitly selecting "FROM" the DO's table - $this->assertContains("FROM \"$baseDBTable\"", $newDQ->sql()); + $this->assertStringContainsString("FROM \"$baseDBTable\"", $newDQ->sql()); //test many_many with shared inheritance $newDQ = new DataQuery(DataQueryTest\ObjectE::class); @@ -113,12 +113,12 @@ class DataQueryTest extends SapphireTest //check we are "joined" to the DataObject's table (there is no distinction between FROM or JOIN clauses) $this->assertTrue($newDQ->query()->isJoinedTo($baseDBTable)); //check we are explicitly selecting "FROM" the DO's table - $this->assertContains("FROM \"$baseDBTable\"", $newDQ->sql(), 'The FROM clause is missing from the query'); + $this->assertStringContainsString("FROM \"$baseDBTable\"", $newDQ->sql(), 'The FROM clause is missing from the query'); $newDQ->applyRelation('ManyTestGs'); //confirm we are still joined to the base table $this->assertTrue($newDQ->query()->isJoinedTo($baseDBTable)); //double check it is the "FROM" clause - $this->assertContains("FROM \"$baseDBTable\"", $newDQ->sql(), 'The FROM clause has been removed from the query'); + $this->assertStringContainsString("FROM \"$baseDBTable\"", $newDQ->sql(), 'The FROM clause has been removed from the query'); //another (potentially less crude check) for checking "FROM" clause $fromTables = $newDQ->query()->getFrom(); $this->assertEquals('"' . $baseDBTable . '"', $fromTables[$baseDBTable]); @@ -171,6 +171,7 @@ class DataQueryTest extends SapphireTest $dataQuery = new DataQuery(DataQueryTest\ObjectB::class); $dataQuery->innerJoin('DataQueryTest_D', '"DataQueryTest_D"."RelationID" = "DataQueryTest_B"."ID"'); $dataQuery->execute(); + $this->assertTrue(true); } public function testDisjunctiveGroup() @@ -256,7 +257,7 @@ class DataQueryTest extends SapphireTest { $dq = new DataQuery(SQLSelectTest\TestObject::class); $dq = $dq->sort('"Name" ASC, MID("Name", 8, 1) DESC'); - $this->assertContains( + $this->assertStringContainsString( 'ORDER BY "SQLSelectTest_DO"."Name" ASC, "_SortColumn0" DESC', $dq->sql($parameters) ); @@ -272,13 +273,13 @@ class DataQueryTest extends SapphireTest public function testDistinct() { $query = new DataQuery(DataQueryTest\ObjectE::class); - $this->assertContains('SELECT DISTINCT', $query->sql($params), 'Query is set as distinct by default'); + $this->assertStringContainsString('SELECT DISTINCT', $query->sql($params), 'Query is set as distinct by default'); $query = $query->distinct(false); - $this->assertNotContains('SELECT DISTINCT', $query->sql($params), 'Query does not contain distinct'); + $this->assertStringNotContainsString('SELECT DISTINCT', $query->sql($params), 'Query does not contain distinct'); $query = $query->distinct(true); - $this->assertContains('SELECT DISTINCT', $query->sql($params), 'Query contains distinct'); + $this->assertStringContainsString('SELECT DISTINCT', $query->sql($params), 'Query contains distinct'); } public function testComparisonClauseInt() diff --git a/tests/php/ORM/DatabaseTest.php b/tests/php/ORM/DatabaseTest.php index 11c513a56..b05020621 100644 --- a/tests/php/ORM/DatabaseTest.php +++ b/tests/php/ORM/DatabaseTest.php @@ -206,21 +206,21 @@ class DatabaseTest extends SapphireTest )->record(); // IDs and ints are returned as ints - $this->assertInternalType('int', $record['ID'], 'Primary key should be integer'); - $this->assertInternalType('int', $record['MyInt'], 'DBInt fields should be integer'); + $this->assertIsInt($record['ID'], 'Primary key should be integer'); + $this->assertIsInt($record['MyInt'], 'DBInt fields should be integer'); - $this->assertInternalType('float', $record['MyFloat'], 'DBFloat fields should be float'); - $this->assertInternalType('float', $record['MyDecimal'], 'DBDecimal fields should be float'); + $this->assertIsFloat($record['MyFloat'], 'DBFloat fields should be float'); + $this->assertIsFloat($record['MyDecimal'], 'DBDecimal fields should be float'); // Booleans are returned as ints – we follow MySQL's lead - $this->assertInternalType('int', $record['MyBoolean'], 'DBBoolean fields should be int'); + $this->assertIsInt($record['MyBoolean'], 'DBBoolean fields should be int'); // Strings and enums are returned as strings - $this->assertInternalType('string', $record['MyField'], 'DBVarchar fields should be string'); - $this->assertInternalType('string', $record['ClassName'], 'DBEnum fields should be string'); + $this->assertIsString($record['MyField'], 'DBVarchar fields should be string'); + $this->assertIsString($record['ClassName'], 'DBEnum fields should be string'); // Dates are returned as strings - $this->assertInternalType('string', $record['Created'], 'DBDatetime fields should be string'); + $this->assertIsString($record['Created'], 'DBDatetime fields should be string'); // Ensure that the same is true when calling a query a second time (cached prepared statement) @@ -231,46 +231,46 @@ class DatabaseTest extends SapphireTest )->record(); // IDs and ints are returned as ints - $this->assertInternalType('int', $record['ID'], 'Primary key should be integer (2nd call)'); - $this->assertInternalType('int', $record['MyInt'], 'DBInt fields should be integer (2nd call)'); + $this->assertIsInt($record['ID'], 'Primary key should be integer (2nd call)'); + $this->assertIsInt($record['MyInt'], 'DBInt fields should be integer (2nd call)'); - $this->assertInternalType('float', $record['MyFloat'], 'DBFloat fields should be float (2nd call)'); - $this->assertInternalType('float', $record['MyDecimal'], 'DBDecimal fields should be float (2nd call)'); + $this->assertIsFloat($record['MyFloat'], 'DBFloat fields should be float (2nd call)'); + $this->assertIsFloat($record['MyDecimal'], 'DBDecimal fields should be float (2nd call)'); // Booleans are returned as ints – we follow MySQL's lead - $this->assertInternalType('int', $record['MyBoolean'], 'DBBoolean fields should be int (2nd call)'); + $this->assertIsInt($record['MyBoolean'], 'DBBoolean fields should be int (2nd call)'); // Strings and enums are returned as strings - $this->assertInternalType('string', $record['MyField'], 'DBVarchar fields should be string (2nd call)'); - $this->assertInternalType('string', $record['ClassName'], 'DBEnum fields should be string (2nd call)'); + $this->assertIsString($record['MyField'], 'DBVarchar fields should be string (2nd call)'); + $this->assertIsString($record['ClassName'], 'DBEnum fields should be string (2nd call)'); // Dates are returned as strings - $this->assertInternalType('string', $record['Created'], 'DBDatetime fields should be string (2nd call)'); + $this->assertIsString($record['Created'], 'DBDatetime fields should be string (2nd call)'); // Ensure that the same is true when using non-prepared statements $record = DB::query('SELECT * FROM "DatabaseTest_MyObject" WHERE "ID" = ' . (int)$obj->ID)->record(); // IDs and ints are returned as ints - $this->assertInternalType('int', $record['ID'], 'Primary key should be integer (non-prepared)'); - $this->assertInternalType('int', $record['MyInt'], 'DBInt fields should be integer (non-prepared)'); + $this->assertIsInt($record['ID'], 'Primary key should be integer (non-prepared)'); + $this->assertIsInt($record['MyInt'], 'DBInt fields should be integer (non-prepared)'); - $this->assertInternalType('float', $record['MyFloat'], 'DBFloat fields should be float (non-prepared)'); - $this->assertInternalType('float', $record['MyDecimal'], 'DBDecimal fields should be float (non-prepared)'); + $this->assertIsFloat($record['MyFloat'], 'DBFloat fields should be float (non-prepared)'); + $this->assertIsFloat($record['MyDecimal'], 'DBDecimal fields should be float (non-prepared)'); // Booleans are returned as ints – we follow MySQL's lead - $this->assertInternalType('int', $record['MyBoolean'], 'DBBoolean fields should be int (non-prepared)'); + $this->assertIsInt($record['MyBoolean'], 'DBBoolean fields should be int (non-prepared)'); // Strings and enums are returned as strings - $this->assertInternalType('string', $record['MyField'], 'DBVarchar fields should be string (non-prepared)'); - $this->assertInternalType('string', $record['ClassName'], 'DBEnum fields should be string (non-prepared)'); + $this->assertIsString($record['MyField'], 'DBVarchar fields should be string (non-prepared)'); + $this->assertIsString($record['ClassName'], 'DBEnum fields should be string (non-prepared)'); // Dates are returned as strings - $this->assertInternalType('string', $record['Created'], 'DBDatetime fields should be string (non-prepared)'); + $this->assertIsString($record['Created'], 'DBDatetime fields should be string (non-prepared)'); // Booleans selected directly are ints $result = DB::query('SELECT TRUE')->first(); - $this->assertInternalType('int', reset($result)); + $this->assertIsInt(reset($result)); } /** diff --git a/tests/php/ORM/DecimalTest.php b/tests/php/ORM/DecimalTest.php index 626fc6d77..c61f81d9f 100644 --- a/tests/php/ORM/DecimalTest.php +++ b/tests/php/ORM/DecimalTest.php @@ -19,7 +19,7 @@ class DecimalTest extends SapphireTest DecimalTest\TestObject::class ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->testDataObject = $this->objFromFixture(DecimalTest\TestObject::class, 'test-dataobject'); diff --git a/tests/php/ORM/HierarchyCachingTest.php b/tests/php/ORM/HierarchyCachingTest.php index 101827117..afbd488c2 100644 --- a/tests/php/ORM/HierarchyCachingTest.php +++ b/tests/php/ORM/HierarchyCachingTest.php @@ -28,13 +28,13 @@ class HierachyCacheTest extends SapphireTest HierarchyOnSubclassTestSubObject::class ]; - public function setUp() + protected function setUp(): void { parent::setUp(); TestObject::singleton()->flushCache(); } - public static function setUpBeforeClass() + public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); HideTestObject::config()->update( diff --git a/tests/php/ORM/HierarchyTest.php b/tests/php/ORM/HierarchyTest.php index 6d4676377..ced863c11 100644 --- a/tests/php/ORM/HierarchyTest.php +++ b/tests/php/ORM/HierarchyTest.php @@ -27,7 +27,7 @@ class HierarchyTest extends SapphireTest return []; } - public function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/ORM/ListDecoratorTest.php b/tests/php/ORM/ListDecoratorTest.php index 6fe45fdd2..2e85f50c9 100644 --- a/tests/php/ORM/ListDecoratorTest.php +++ b/tests/php/ORM/ListDecoratorTest.php @@ -2,7 +2,8 @@ namespace SilverStripe\ORM\Tests; -use PHPUnit_Framework_MockObject_MockObject; +use LogicException; +use PHPUnit\Framework\MockObject\MockObject; use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ListDecorator; @@ -14,16 +15,16 @@ use SilverStripe\ORM\SS_List; class ListDecoratorTest extends SapphireTest { /** - * @var ArrayList|PHPUnit_Framework_MockObject_MockObject + * @var ArrayList|MockObject */ protected $list; /** - * @var ListDecorator|PHPUnit_Framework_MockObject_MockObject + * @var ListDecorator|MockObject */ protected $decorator; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -108,12 +109,10 @@ class ListDecoratorTest extends SapphireTest $this->assertFalse($this->decorator->canFilterBy('Title')); } - /** - * @expectedException \LogicException - * @expectedExceptionMessage SS_Filterable::filterByCallback() passed callback must be callable, 'boolean' given - */ public function testFilterByCallbackThrowsExceptionWhenGivenNonCallable() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage("SS_Filterable::filterByCallback() passed callback must be callable, 'boolean' given"); $this->decorator->filterByCallback(true); } diff --git a/tests/php/ORM/ManyManyListTest.php b/tests/php/ORM/ManyManyListTest.php index 373105289..ce1db5ebb 100644 --- a/tests/php/ORM/ManyManyListTest.php +++ b/tests/php/ORM/ManyManyListTest.php @@ -444,7 +444,7 @@ class ManyManyListTest extends SapphireTest public function testWriteManipulationWithNonScalarValuesDisallowed() { - $this->expectException(InvalidArgumentException::class); + $this->expectException(\InvalidArgumentException::class); $left = DataObjectTest\MockDynamicAssignmentDataObject::create(); $left->write(); diff --git a/tests/php/ORM/ManyManyThroughListTest.php b/tests/php/ORM/ManyManyThroughListTest.php index 04a3616b2..905cc814b 100644 --- a/tests/php/ORM/ManyManyThroughListTest.php +++ b/tests/php/ORM/ManyManyThroughListTest.php @@ -2,6 +2,7 @@ namespace SilverStripe\ORM\Tests; +use InvalidArgumentException; use SilverStripe\Core\Config\Config; use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\DataObject; @@ -31,13 +32,13 @@ class ManyManyThroughListTest extends SapphireTest ManyManyThroughListTest\FallbackLocale::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); DataObject::reset(); } - protected function tearDown() + protected function tearDown(): void { DataObject::reset(); parent::tearDown(); @@ -204,11 +205,10 @@ class ManyManyThroughListTest extends SapphireTest /** * Test validation - * - * @expectedException \InvalidArgumentException */ public function testValidateModelValidatesJoinType() { + $this->expectException(\InvalidArgumentException::class); DataObject::reset(); ManyManyThroughListTest\Item::config()->update( 'db', diff --git a/tests/php/ORM/MarkedSetTest.php b/tests/php/ORM/MarkedSetTest.php index bdd8a9523..c88ef1b64 100644 --- a/tests/php/ORM/MarkedSetTest.php +++ b/tests/php/ORM/MarkedSetTest.php @@ -31,7 +31,7 @@ class MarkedSetTest extends SapphireTest return []; } - public function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/ORM/PaginatedListTest.php b/tests/php/ORM/PaginatedListTest.php index cc076b08c..dd9e30b69 100644 --- a/tests/php/ORM/PaginatedListTest.php +++ b/tests/php/ORM/PaginatedListTest.php @@ -329,7 +329,7 @@ class PaginatedListTest extends SapphireTest public function testFirstLink() { $list = new PaginatedList(new ArrayList()); - $this->assertContains('start=0', $list->FirstLink()); + $this->assertStringContainsString('start=0', $list->FirstLink()); } public function testFirstLinkContainsCurrentGetParameters() @@ -358,11 +358,11 @@ class PaginatedListTest extends SapphireTest $list = new PaginatedList(new ArrayList()); $list->setPageLength(10); $list->setTotalItems(100); - $this->assertContains('start=90', $list->LastLink()); + $this->assertStringContainsString('start=90', $list->LastLink()); // Disable paging $list->setPageLength(0); - $this->assertContains('start=0', $list->LastLink()); + $this->assertStringContainsString('start=0', $list->LastLink()); } public function testLastLinkContainsCurrentGetParameters() @@ -391,13 +391,13 @@ class PaginatedListTest extends SapphireTest $list = new PaginatedList(new ArrayList()); $list->setTotalItems(50); - $this->assertContains('start=10', $list->NextLink()); + $this->assertStringContainsString('start=10', $list->NextLink()); $list->setCurrentPage(2); - $this->assertContains('start=20', $list->NextLink()); + $this->assertStringContainsString('start=20', $list->NextLink()); $list->setCurrentPage(3); - $this->assertContains('start=30', $list->NextLink()); + $this->assertStringContainsString('start=30', $list->NextLink()); $list->setCurrentPage(4); - $this->assertContains('start=40', $list->NextLink()); + $this->assertStringContainsString('start=40', $list->NextLink()); $list->setCurrentPage(5); $this->assertNull($list->NextLink()); @@ -435,11 +435,11 @@ class PaginatedListTest extends SapphireTest $this->assertNull($list->PrevLink()); $list->setCurrentPage(2); - $this->assertContains('start=0', $list->PrevLink()); + $this->assertStringContainsString('start=0', $list->PrevLink()); $list->setCurrentPage(3); - $this->assertContains('start=10', $list->PrevLink()); + $this->assertStringContainsString('start=10', $list->PrevLink()); $list->setCurrentPage(5); - $this->assertContains('start=30', $list->PrevLink()); + $this->assertStringContainsString('start=30', $list->PrevLink()); // Disable paging $list->setPageLength(0); diff --git a/tests/php/ORM/SQLSelectTest.php b/tests/php/ORM/SQLSelectTest.php index 45c6e0d11..cf21b45f6 100755 --- a/tests/php/ORM/SQLSelectTest.php +++ b/tests/php/ORM/SQLSelectTest.php @@ -2,6 +2,7 @@ namespace SilverStripe\ORM\Tests; +use InvalidArgumentException; use SilverStripe\ORM\DB; use SilverStripe\ORM\Connect\MySQLDatabase; use SilverStripe\ORM\Queries\SQLSelect; @@ -23,13 +24,13 @@ class SQLSelectTest extends SapphireTest protected $oldDeprecation = null; - protected function setUp() + protected function setUp(): void { parent::setUp(); $this->oldDeprecation = Deprecation::dump_settings(); } - protected function tearDown() + protected function tearDown(): void { Deprecation::restore_settings($this->oldDeprecation); parent::tearDown(); @@ -43,7 +44,7 @@ class SQLSelectTest extends SapphireTest $ids = $this->allFixtureIDs(SQLSelectTest\TestObject::class); $count = $qry->count('"SQLSelectTest_DO"."ID"'); $this->assertEquals(count($ids), $count); - $this->assertInternalType("int", $count); + $this->assertIsInt($count); //test with `having` if (DB::get_conn() instanceof MySQLDatabase) { $qry->setSelect([ @@ -54,7 +55,7 @@ class SQLSelectTest extends SapphireTest $qry->setHaving('"Date" > 2012-02-01'); $count = $qry->count('"SQLSelectTest_DO"."ID"'); $this->assertEquals(1, $count); - $this->assertInternalType("int", $count); + $this->assertIsInt($count); } } public function testUnlimitedRowCount() @@ -65,17 +66,17 @@ class SQLSelectTest extends SapphireTest $qry->setLimit(1); $count = $qry->unlimitedRowCount('"SQLSelectTest_DO"."ID"'); $this->assertEquals(count($ids), $count); - $this->assertInternalType("int", $count); + $this->assertIsInt($count); // Test without column - SQLSelect has different logic for this $count = $qry->unlimitedRowCount(); $this->assertEquals(2, $count); - $this->assertInternalType("int", $count); + $this->assertIsInt($count); //test with `having` if (DB::get_conn() instanceof MySQLDatabase) { $qry->setHaving('"Date" > 2012-02-01'); $count = $qry->unlimitedRowCount('"SQLSelectTest_DO"."ID"'); $this->assertEquals(1, $count); - $this->assertInternalType("int", $count); + $this->assertIsInt($count); } } @@ -267,57 +268,23 @@ class SQLSelectTest extends SapphireTest ); } - /** - * @expectedException PHPUnit_Framework_Error - */ - public function testZeroLimit() - { - Deprecation::notification_version('4.3.0'); - $query = new SQLSelect(); - $query->setFrom("MyTable"); - $query->setLimit(0); - } - - /** - * @expectedException PHPUnit_Framework_Error - */ - public function testZeroLimitWithOffset() - { - Deprecation::notification_version('4.3.0'); - if (!(DB::get_conn() instanceof MySQLDatabase || DB::get_conn() instanceof SQLite3Database - || DB::get_conn() instanceof PostgreSQLDatabase) - ) { - $this->markTestIncomplete(); - } - - $query = new SQLSelect(); - $query->setFrom("MyTable"); - $query->setLimit(0, 99); - } - - /** - * @expectedException InvalidArgumentException - */ public function testNegativeLimit() { + $this->expectException(\InvalidArgumentException::class); $query = new SQLSelect(); $query->setLimit(-10); } - /** - * @expectedException InvalidArgumentException - */ public function testNegativeOffset() { + $this->expectException(\InvalidArgumentException::class); $query = new SQLSelect(); $query->setLimit(1, -10); } - /** - * @expectedException InvalidArgumentException - */ public function testNegativeOffsetAndLimit() { + $this->expectException(\InvalidArgumentException::class); $query = new SQLSelect(); $query->setLimit(-10, -10); } diff --git a/tests/php/ORM/Search/FulltextSearchableTest.php b/tests/php/ORM/Search/FulltextSearchableTest.php index 7355f381b..544f31d2e 100644 --- a/tests/php/ORM/Search/FulltextSearchableTest.php +++ b/tests/php/ORM/Search/FulltextSearchableTest.php @@ -12,7 +12,7 @@ use SilverStripe\ORM\Search\FulltextSearchable; class FulltextSearchableTest extends SapphireTest { - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -24,7 +24,7 @@ class FulltextSearchableTest extends SapphireTest * properly at the end of the test. This becomes apparent when a later test tries to * ALTER TABLE File and add fulltext indexes with the InnoDB table type. */ - protected function tearDown() + protected function tearDown(): void { parent::tearDown(); diff --git a/tests/php/ORM/TransactionTest.php b/tests/php/ORM/TransactionTest.php index 075c788d4..7c1a02a0c 100644 --- a/tests/php/ORM/TransactionTest.php +++ b/tests/php/ORM/TransactionTest.php @@ -20,19 +20,19 @@ class TransactionTest extends SapphireTest private static $originalVersionInfo; - protected function setUp() + protected function setUp(): void { parent::setUp(); self::$originalVersionInfo = Deprecation::dump_settings(); } - protected function tearDown() + protected function tearDown(): void { Deprecation::restore_settings(self::$originalVersionInfo); parent::tearDown(); } - public static function setUpBeforeClass() + public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); if (!DB::get_conn()->supportsTransactions()) { @@ -192,7 +192,7 @@ class TransactionTest extends SapphireTest $fail = DataObject::get_one(TestObject::class, "\"Title\"='Read only page failed'"); //This page should be in the system - $this->assertInternalType('object', $success); + $this->assertIsObject($success); $this->assertTrue($success->exists()); //This page should NOT exist, we had 'read only' permissions diff --git a/tests/php/ORM/ValidationExceptionTest.php b/tests/php/ORM/ValidationExceptionTest.php index 978d0fc00..28253e297 100644 --- a/tests/php/ORM/ValidationExceptionTest.php +++ b/tests/php/ORM/ValidationExceptionTest.php @@ -8,6 +8,16 @@ use SilverStripe\Dev\SapphireTest; class ValidationExceptionTest extends SapphireTest { + private function arrayContainsArray($expectedSubArray, $array) + { + foreach ($array as $subArray) { + if ($subArray == $expectedSubArray) { + return true; + } + } + return false; + } + /** * Test that ValidationResult object can correctly populate a ValidationException */ @@ -21,15 +31,13 @@ class ValidationExceptionTest extends SapphireTest $this->assertEquals(0, $exception->getCode()); $this->assertEquals('Not a valid result', $exception->getMessage()); $this->assertFalse($exception->getResult()->isValid()); - $this->assertContains( - [ + $b = $this->arrayContainsArray([ 'message' => 'Not a valid result', 'messageCast' => ValidationResult::CAST_TEXT, 'messageType' => ValidationResult::TYPE_ERROR, 'fieldName' => null, - ], - $exception->getResult()->getMessages() - ); + ], $exception->getResult()->getMessages()); + $this->assertTrue($b, 'Messages array should contain expected messaged'); } /** @@ -47,24 +55,22 @@ class ValidationExceptionTest extends SapphireTest $this->assertEquals(0, $exception->getCode()); $this->assertEquals('Invalid type', $exception->getMessage()); $this->assertEquals(false, $exception->getResult()->isValid()); - $this->assertContains( - [ + + $b = $this->arrayContainsArray([ 'message' => 'Invalid type', 'messageCast' => ValidationResult::CAST_TEXT, 'messageType' => ValidationResult::TYPE_ERROR, 'fieldName' => null, - ], - $exception->getResult()->getMessages() - ); - $this->assertContains( - [ + ], $exception->getResult()->getMessages()); + $this->assertTrue($b, 'Messages array should contain expected messaged'); + + $b = $this->arrayContainsArray([ 'message' => 'Out of kiwis', 'messageCast' => ValidationResult::CAST_TEXT, 'messageType' => ValidationResult::TYPE_ERROR, 'fieldName' => null, - ], - $exception->getResult()->getMessages() - ); + ], $exception->getResult()->getMessages()); + $this->assertTrue($b, 'Messages array should contain expected messaged'); } /** @@ -78,15 +84,14 @@ class ValidationExceptionTest extends SapphireTest $this->assertEquals(E_USER_ERROR, $exception->getCode()); $this->assertEquals('Error inferred from message', $exception->getMessage()); $this->assertFalse($exception->getResult()->isValid()); - $this->assertContains( - [ + + $b = $this->arrayContainsArray([ 'message' => 'Error inferred from message', 'messageCast' => ValidationResult::CAST_TEXT, 'messageType' => ValidationResult::TYPE_ERROR, 'fieldName' => null, - ], - $exception->getResult()->getMessages() - ); + ], $exception->getResult()->getMessages()); + $this->assertTrue($b, 'Messages array should contain expected messaged'); } /** @@ -103,24 +108,22 @@ class ValidationExceptionTest extends SapphireTest $this->assertEquals(E_USER_WARNING, $exception->getCode()); $this->assertEquals('A spork is not a knife', $exception->getMessage()); $this->assertEquals(false, $exception->getResult()->isValid()); - $this->assertContains( - [ + + $b = $this->arrayContainsArray([ 'message' => 'A spork is not a knife', 'messageCast' => ValidationResult::CAST_TEXT, 'messageType' => ValidationResult::TYPE_ERROR, 'fieldName' => null, - ], - $exception->getResult()->getMessages() - ); - $this->assertContains( - [ + ], $exception->getResult()->getMessages()); + $this->assertTrue($b, 'Messages array should contain expected messaged'); + + $b = $this->arrayContainsArray([ 'message' => 'A knife is not a back scratcher', 'messageCast' => ValidationResult::CAST_TEXT, 'messageType' => ValidationResult::TYPE_ERROR, 'fieldName' => null, - ], - $exception->getResult()->getMessages() - ); + ], $exception->getResult()->getMessages()); + $this->assertTrue($b, 'Messages array should contain expected messaged'); } /** @@ -175,30 +178,30 @@ class ValidationExceptionTest extends SapphireTest $this->assertEquals( [ - [ - 'fieldName' => null, - 'message' => 'A spork is not a knife', - 'messageType' => 'bad', - 'messageCast' => ValidationResult::CAST_TEXT, - ], - [ - 'fieldName' => null, - 'message' => 'A knife is not a back scratcher', - 'messageType' => 'error', - 'messageCast' => ValidationResult::CAST_TEXT, - ], - [ - 'fieldName' => 'Title', - 'message' => 'Title is good', - 'messageType' => 'good', - 'messageCast' => ValidationResult::CAST_TEXT, - ], - [ - 'fieldName' => 'Content', - 'message' => 'Content is bad', - 'messageType' => 'bad', - 'messageCast' => ValidationResult::CAST_TEXT, - ] + [ + 'fieldName' => null, + 'message' => 'A spork is not a knife', + 'messageType' => 'bad', + 'messageCast' => ValidationResult::CAST_TEXT, + ], + [ + 'fieldName' => null, + 'message' => 'A knife is not a back scratcher', + 'messageType' => 'error', + 'messageCast' => ValidationResult::CAST_TEXT, + ], + [ + 'fieldName' => 'Title', + 'message' => 'Title is good', + 'messageType' => 'good', + 'messageCast' => ValidationResult::CAST_TEXT, + ], + [ + 'fieldName' => 'Content', + 'message' => 'Content is bad', + 'messageType' => 'bad', + 'messageCast' => ValidationResult::CAST_TEXT, + ] ], $result->getMessages() ); diff --git a/tests/php/Security/BasicAuthTest.php b/tests/php/Security/BasicAuthTest.php index ffb95f0bf..94d8b7af1 100644 --- a/tests/php/Security/BasicAuthTest.php +++ b/tests/php/Security/BasicAuthTest.php @@ -26,7 +26,7 @@ class BasicAuthTest extends FunctionalTest ControllerNotSecured::class, ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Security/GroupTest.php b/tests/php/Security/GroupTest.php index 12b253551..79d446311 100644 --- a/tests/php/Security/GroupTest.php +++ b/tests/php/Security/GroupTest.php @@ -20,7 +20,7 @@ class GroupTest extends FunctionalTest TestMember::class ]; - protected function setUp() + protected function setUp(): void { parent::setUp(); } @@ -164,7 +164,7 @@ class GroupTest extends FunctionalTest */ public function testCannotCollateUnsavedGroupFamilyIds() { - $this->expectException(InvalidArgumentException::class); + $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('Cannot call collateFamilyIDs on unsaved Group.'); $group = new Group; $group->collateFamilyIDs(); diff --git a/tests/php/Security/InheritedPermissionsFlusherTest.php b/tests/php/Security/InheritedPermissionsFlusherTest.php index 8cadcd0cc..4aea948b1 100644 --- a/tests/php/Security/InheritedPermissionsFlusherTest.php +++ b/tests/php/Security/InheritedPermissionsFlusherTest.php @@ -15,7 +15,7 @@ class InheritedPermissionsFlusherTest extends SapphireTest { protected static $fixture_file = 'InheritedPermissionsFlusherTest.yml'; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Security/InheritedPermissionsTest.php b/tests/php/Security/InheritedPermissionsTest.php index 5aa32de65..696351030 100644 --- a/tests/php/Security/InheritedPermissionsTest.php +++ b/tests/php/Security/InheritedPermissionsTest.php @@ -29,7 +29,7 @@ class InheritedPermissionsTest extends SapphireTest */ protected $rootPermissions = null; - protected function setUp() + protected function setUp(): void { $this->rootPermissions = new TestDefaultPermissionChecker(); @@ -57,7 +57,7 @@ class InheritedPermissionsTest extends SapphireTest $permission2->clearCache(); } - protected function tearDown() + protected function tearDown(): void { Injector::inst()->unregisterNamedObject(PermissionChecker::class . '.testpermissions'); Injector::inst()->unregisterNamedObject(PermissionChecker::class . '.unstagedpermissions'); diff --git a/tests/php/Security/MemberAuthenticator/ChangePasswordHandlerTest.php b/tests/php/Security/MemberAuthenticator/ChangePasswordHandlerTest.php index 16fbcad2d..f318d01f3 100644 --- a/tests/php/Security/MemberAuthenticator/ChangePasswordHandlerTest.php +++ b/tests/php/Security/MemberAuthenticator/ChangePasswordHandlerTest.php @@ -15,7 +15,7 @@ class ChangePasswordHandlerTest extends SapphireTest { protected static $fixture_file = 'ChangePasswordHandlerTest.yml'; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -42,8 +42,8 @@ class ChangePasswordHandlerTest extends SapphireTest $result = $handler->setRequest($request)->changepassword(); - $this->assertInternalType('array', $result, 'An array is returned'); - $this->assertContains('Security/lostpassword', $result['Content'], 'Lost password URL is included'); - $this->assertContains('Security/login', $result['Content'], 'Login URL is included'); + $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/MemberAuthenticatorTest.php b/tests/php/Security/MemberAuthenticatorTest.php index 9dd6df12d..ff0df93e6 100644 --- a/tests/php/Security/MemberAuthenticatorTest.php +++ b/tests/php/Security/MemberAuthenticatorTest.php @@ -32,7 +32,7 @@ class MemberAuthenticatorTest extends SapphireTest protected $defaultUsername = null; protected $defaultPassword = null; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -52,7 +52,7 @@ class MemberAuthenticatorTest extends SapphireTest ->setTestNames([]); } - protected function tearDown() + protected function tearDown(): void { DefaultAdminService::clearDefaultAdmin(); if ($this->defaultUsername) { diff --git a/tests/php/Security/MemberCsvBulkLoaderTest.php b/tests/php/Security/MemberCsvBulkLoaderTest.php index 76993616a..5387fe8f9 100644 --- a/tests/php/Security/MemberCsvBulkLoaderTest.php +++ b/tests/php/Security/MemberCsvBulkLoaderTest.php @@ -14,7 +14,7 @@ class MemberCsvBulkLoaderTest extends SapphireTest { protected static $fixture_file = 'MemberCsvBulkLoaderTest.yml'; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Security/MemberTest.php b/tests/php/Security/MemberTest.php index 49d543a75..420bb8102 100644 --- a/tests/php/Security/MemberTest.php +++ b/tests/php/Security/MemberTest.php @@ -39,7 +39,7 @@ class MemberTest extends FunctionalTest Member::class => '*', ]; - public static function setUpBeforeClass() + public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); @@ -63,7 +63,7 @@ class MemberTest extends FunctionalTest /** * @skipUpgrade */ - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -104,11 +104,10 @@ class MemberTest extends FunctionalTest $m2->write(); } - /** - * @expectedException \SilverStripe\ORM\ValidationException - */ public function testWriteDoesntMergeExistingMemberOnIdentifierChange() { + $this->expectException(ValidationException::class); + $m1 = new Member(); $m1->Email = 'member@test.com'; $m1->write(); @@ -256,7 +255,7 @@ class MemberTest extends FunctionalTest $this->assertEquals($response->getStatusCode(), 302); // We should get redirected to Security/passwordsent - $this->assertContains( + $this->assertStringContainsString( 'Security/lostpassword/passwordsent', urldecode($response->getHeader('Location')) ); @@ -1011,7 +1010,7 @@ class MemberTest extends FunctionalTest ['name' => $m1->FirstName] ) ); - $this->assertContains($message, $response->getBody()); + $this->assertStringContainsString($message, $response->getBody()); $this->logOut(); @@ -1025,7 +1024,7 @@ class MemberTest extends FunctionalTest 'alc_device' => $firstHash->DeviceID ] ); - $this->assertNotContains($message, $response->getBody()); + $this->assertStringNotContainsString($message, $response->getBody()); $response = $this->get( 'Security/login', @@ -1036,7 +1035,7 @@ class MemberTest extends FunctionalTest 'alc_device' => str_rot13($firstHash->DeviceID) ] ); - $this->assertNotContains($message, $response->getBody()); + $this->assertStringNotContainsString($message, $response->getBody()); // Re-logging (ie 'alc_enc' has expired), and not checking the "Remember Me" option // should remove all previous hashes for this device @@ -1054,7 +1053,7 @@ class MemberTest extends FunctionalTest 'alc_device' => $firstHash->DeviceID ] ); - $this->assertContains($message, $response->getBody()); + $this->assertStringContainsString($message, $response->getBody()); $this->assertEquals(RememberLoginHash::get()->filter('MemberID', $m1->ID)->count(), 0); } @@ -1091,7 +1090,7 @@ class MemberTest extends FunctionalTest ['name' => $m1->FirstName] ) ); - $this->assertContains($message, $response->getBody()); + $this->assertStringContainsString($message, $response->getBody()); $this->logOut(); @@ -1112,7 +1111,7 @@ class MemberTest extends FunctionalTest 'alc_device' => $firstHash->DeviceID ] ); - $this->assertNotContains($message, $response->getBody()); + $this->assertStringNotContainsString($message, $response->getBody()); $this->logOut(); DBDatetime::clear_mock_now(); } @@ -1167,7 +1166,7 @@ class MemberTest extends FunctionalTest ['name' => $m1->FirstName] ) ); - $this->assertContains($message, $response->getBody()); + $this->assertStringContainsString($message, $response->getBody()); // Test that removing session but not cookie keeps user /** @var SessionAuthenticationHandler $sessionHandler */ @@ -1185,7 +1184,7 @@ class MemberTest extends FunctionalTest 'alc_device' => $secondHash->DeviceID ] ); - $this->assertContains($message, $response->getBody()); + $this->assertStringContainsString($message, $response->getBody()); // Logging out from the second device - only one device being logged out RememberLoginHash::config()->update('logout_across_devices', false); @@ -1608,6 +1607,7 @@ class MemberTest extends FunctionalTest public function testChangePasswordToBlankIsValidated() { + Member::set_password_validator(new PasswordValidator()); // override setup() function which setMinLength(0) PasswordValidator::singleton()->setMinLength(8); // 'test' member has a password defined in yml diff --git a/tests/php/Security/PasswordEncryptorTest.php b/tests/php/Security/PasswordEncryptorTest.php index 11f2e76e4..38b11c533 100644 --- a/tests/php/Security/PasswordEncryptorTest.php +++ b/tests/php/Security/PasswordEncryptorTest.php @@ -7,12 +7,13 @@ use SilverStripe\Security\PasswordEncryptor; use SilverStripe\Core\Config\Config; use SilverStripe\Dev\SapphireTest; use SilverStripe\Security\PasswordEncryptor_LegacyPHPHash; +use SilverStripe\Security\PasswordEncryptor_NotFoundException; use SilverStripe\Security\PasswordEncryptor_PHPHash; use SilverStripe\Security\Tests\PasswordEncryptorTest\TestEncryptor; class PasswordEncryptorTest extends SapphireTest { - protected function tearDown() + protected function tearDown(): void { parent::tearDown(); PasswordEncryptor_Blowfish::set_cost(10); @@ -29,11 +30,9 @@ class PasswordEncryptorTest extends SapphireTest $this->assertInstanceOf(TestEncryptor::class, $e); } - /** - * @expectedException \SilverStripe\Security\PasswordEncryptor_NotFoundException - */ public function testCreateForCodeNotFound() { + $this->expectException(PasswordEncryptor_NotFoundException::class); PasswordEncryptor::create_for_algorithm('unknown'); } @@ -47,7 +46,7 @@ class PasswordEncryptorTest extends SapphireTest $encryptors = PasswordEncryptor::get_encryptors(); $this->assertContains('test', array_keys($encryptors)); $encryptor = $encryptors['test']; - $this->assertContains(TestEncryptor::class, key($encryptor)); + $this->assertStringContainsString(TestEncryptor::class, key($encryptor)); } public function testEncryptorPHPHashWithArguments() diff --git a/tests/php/Security/PasswordExpirationMiddlewareTest.php b/tests/php/Security/PasswordExpirationMiddlewareTest.php index 53136b92c..ce3799e0b 100644 --- a/tests/php/Security/PasswordExpirationMiddlewareTest.php +++ b/tests/php/Security/PasswordExpirationMiddlewareTest.php @@ -14,7 +14,7 @@ class PasswordExpirationMiddlewareTest extends SapphireTest { use HttpRequestMockBuilder; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Security/PasswordValidatorTest.php b/tests/php/Security/PasswordValidatorTest.php index 071e50760..560a8f255 100644 --- a/tests/php/Security/PasswordValidatorTest.php +++ b/tests/php/Security/PasswordValidatorTest.php @@ -14,7 +14,7 @@ class PasswordValidatorTest extends SapphireTest */ protected $usesDatabase = true; - protected function setUp() + protected function setUp(): void { parent::setUp(); diff --git a/tests/php/Security/PermissionCheckboxSetFieldTest.php b/tests/php/Security/PermissionCheckboxSetFieldTest.php index bfd61f272..c7b403c69 100644 --- a/tests/php/Security/PermissionCheckboxSetFieldTest.php +++ b/tests/php/Security/PermissionCheckboxSetFieldTest.php @@ -30,8 +30,8 @@ class PermissionCheckboxSetFieldTest extends SapphireTest $f->getHiddenPermissions(), ['NON-ADMIN'] ); - $this->assertContains('ADMIN', $f->Field()); - $this->assertNotContains('NON-ADMIN', $f->Field()); + $this->assertStringContainsString('ADMIN', $f->Field()); + $this->assertStringNotContainsString('NON-ADMIN', $f->Field()); } public function testSaveInto() diff --git a/tests/php/Security/PermissionTest.php b/tests/php/Security/PermissionTest.php index 656949841..109fb2516 100644 --- a/tests/php/Security/PermissionTest.php +++ b/tests/php/Security/PermissionTest.php @@ -143,14 +143,14 @@ class PermissionTest extends SapphireTest public function testHiddenPermissions() { $permissionCheckboxSet = new PermissionCheckboxSetField('Permissions', 'Permissions', Permission::class, 'GroupID'); - $this->assertContains('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field()); + $this->assertStringContainsString('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field()); Config::modify()->merge(Permission::class, 'hidden_permissions', ['CMS_ACCESS_LeftAndMain']); - $this->assertNotContains('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field()); + $this->assertStringNotContainsString('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field()); Config::inst()->remove(Permission::class, 'hidden_permissions'); - $this->assertContains('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field()); + $this->assertStringContainsString('CMS_ACCESS_LeftAndMain', $permissionCheckboxSet->Field()); } public function testEmptyMemberFails() diff --git a/tests/php/Security/RememberLoginHashTest.php b/tests/php/Security/RememberLoginHashTest.php index 3ef236a6b..492ded89b 100644 --- a/tests/php/Security/RememberLoginHashTest.php +++ b/tests/php/Security/RememberLoginHashTest.php @@ -14,7 +14,7 @@ class RememberLoginHashTest extends SapphireTest /** @var RememberLoginHash[] */ private $loginHash = []; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -43,12 +43,12 @@ class RememberLoginHashTest extends SapphireTest /** * @param bool $logoutAcrossDevices - * @param string $deviceId + * @param mixed $deviceId * @param array $expected * @param array $unexpected * @dataProvider clearScenarios */ - public function testClear(bool $logoutAcrossDevices, string $deviceId, array $expected, array $unexpected) + public function testClear(bool $logoutAcrossDevices, $deviceId, array $expected, array $unexpected) { // If session-manager module is installed then logout_across_devices is modified so skip if (class_exists(LoginSession::class)) { diff --git a/tests/php/Security/SecurityDefaultAdminTest.php b/tests/php/Security/SecurityDefaultAdminTest.php index 9b40dd9fb..9571bf03a 100644 --- a/tests/php/Security/SecurityDefaultAdminTest.php +++ b/tests/php/Security/SecurityDefaultAdminTest.php @@ -16,7 +16,7 @@ class SecurityDefaultAdminTest extends SapphireTest protected $defaultPassword = null; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -39,7 +39,7 @@ class SecurityDefaultAdminTest extends SapphireTest Permission::reset(); } - protected function tearDown() + protected function tearDown(): void { DefaultAdminService::clearDefaultAdmin(); if ($this->defaultUsername) { diff --git a/tests/php/Security/SecurityTest.php b/tests/php/Security/SecurityTest.php index 7e21dbaf5..140716163 100644 --- a/tests/php/Security/SecurityTest.php +++ b/tests/php/Security/SecurityTest.php @@ -42,7 +42,7 @@ class SecurityTest extends FunctionalTest SecurityTest\SecuredController::class, ]; - protected function setUp() + protected function setUp(): void { // Set to an empty array of authenticators to enable the default Config::modify()->set(MemberAuthenticator::class, 'authenticators', []); @@ -82,7 +82,7 @@ class SecurityTest extends FunctionalTest $response = $this->get('SecurityTest_SecuredController'); $this->assertEquals(302, $response->getStatusCode()); - $this->assertContains( + $this->assertStringContainsString( Config::inst()->get(Security::class, 'login_url'), $response->getHeader('Location') ); @@ -90,7 +90,7 @@ class SecurityTest extends FunctionalTest $this->logInWithPermission('ADMIN'); $response = $this->get('SecurityTest_SecuredController'); $this->assertEquals(200, $response->getStatusCode()); - $this->assertContains('Success', $response->getBody()); + $this->assertStringContainsString('Success', $response->getBody()); $this->autoFollowRedirection = true; } @@ -135,7 +135,7 @@ class SecurityTest extends FunctionalTest ['default' => 'default', 'alreadyLoggedIn' => 'You are already logged in!'] ); Security::permissionFailure($controller); - $this->assertContains( + $this->assertStringContainsString( 'You are already logged in!', $controller->getResponse()->getBody(), 'Custom permission failure message was ignored' @@ -145,7 +145,7 @@ class SecurityTest extends FunctionalTest $controller, ['default' => 'default', 'alreadyLoggedIn' => 'One-off failure message'] ); - $this->assertContains( + $this->assertStringContainsString( 'One-off failure message', $controller->getResponse()->getBody(), "Message set passed to Security::permissionFailure() didn't override Config values" @@ -156,7 +156,7 @@ class SecurityTest extends FunctionalTest $controller, DBField::create_field('HTMLFragment', '

Custom HTML & Message

') ); - $this->assertContains( + $this->assertStringContainsString( '

Custom HTML & Message

', $controller->getResponse()->getBody() ); @@ -166,7 +166,7 @@ class SecurityTest extends FunctionalTest $controller, DBField::create_field('Text', 'Safely escaped & message') ); - $this->assertContains( + $this->assertStringContainsString( 'Safely escaped & message', $controller->getResponse()->getBody() ); @@ -196,29 +196,29 @@ class SecurityTest extends FunctionalTest Security::setCurrentUser(null); } $response = $this->getRecursive('SecurityTest_SecuredController'); - $this->assertContains(Convert::raw2xml("That page is secured."), $response->getBody()); - $this->assertContains('getBody()); + $this->assertStringContainsString(Convert::raw2xml("That page is secured."), $response->getBody()); + $this->assertStringContainsString('getBody()); // Non-logged in user should not be redirected, but instead shown the login form // No message/context is available as the user has not attempted to view the secured controller $response = $this->getRecursive('Security/login?BackURL=SecurityTest_SecuredController/'); - $this->assertNotContains(Convert::raw2xml("That page is secured."), $response->getBody()); - $this->assertNotContains(Convert::raw2xml("You don't have access to this page"), $response->getBody()); - $this->assertContains('getBody()); + $this->assertStringNotContainsString(Convert::raw2xml("That page is secured."), $response->getBody()); + $this->assertStringNotContainsString(Convert::raw2xml("You don't have access to this page"), $response->getBody()); + $this->assertStringContainsString('getBody()); // BackURL with permission error (wrong permissions) should not redirect $this->logInAs('grouplessmember'); $response = $this->getRecursive('SecurityTest_SecuredController'); - $this->assertContains(Convert::raw2xml("You don't have access to this page"), $response->getBody()); - $this->assertContains( + $this->assertStringContainsString(Convert::raw2xml("You don't have access to this page"), $response->getBody()); + $this->assertStringContainsString( 'getBody() ); // Directly accessing this page should attempt to follow the BackURL, but stop when it encounters the error $response = $this->getRecursive('Security/login?BackURL=SecurityTest_SecuredController/'); - $this->assertContains(Convert::raw2xml("You don't have access to this page"), $response->getBody()); - $this->assertContains( + $this->assertStringContainsString(Convert::raw2xml("You don't have access to this page"), $response->getBody()); + $this->assertStringContainsString( 'getBody() ); @@ -226,11 +226,11 @@ class SecurityTest extends FunctionalTest // Check correctly logged in admin doesn't generate the same errors $this->logInAs('admin'); $response = $this->getRecursive('SecurityTest_SecuredController'); - $this->assertContains(Convert::raw2xml("Success"), $response->getBody()); + $this->assertStringContainsString(Convert::raw2xml("Success"), $response->getBody()); // Directly accessing this page should attempt to follow the BackURL and succeed $response = $this->getRecursive('Security/login?BackURL=SecurityTest_SecuredController/'); - $this->assertContains(Convert::raw2xml("Success"), $response->getBody()); + $this->assertStringContainsString(Convert::raw2xml("Success"), $response->getBody()); } public function testLogInAsSomeoneElse() @@ -356,7 +356,7 @@ class SecurityTest extends FunctionalTest /* We get a good response */ $this->assertEquals(302, $response->getStatusCode()); - $this->assertRegExp( + $this->assertMatchesRegularExpression( '/testpage/', $response->getHeader('Location'), "Logout form redirects to back to referer." @@ -376,7 +376,7 @@ class SecurityTest extends FunctionalTest // Test internal relative redirect $response = $this->doTestLoginForm('noexpiry@silverstripe.com', '1nitialPassword', 'testpage'); $this->assertEquals(302, $response->getStatusCode()); - $this->assertRegExp( + $this->assertMatchesRegularExpression( '/testpage/', $response->getHeader('Location'), "Internal relative BackURLs work when passed through to login form" @@ -391,7 +391,7 @@ class SecurityTest extends FunctionalTest Director::absoluteBaseURL() . 'testpage' ); // for some reason the redirect happens to a relative URL - $this->assertRegExp( + $this->assertMatchesRegularExpression( '/^' . preg_quote(Director::absoluteBaseURL(), '/') . 'testpage/', $response->getHeader('Location'), "Internal absolute BackURLs work when passed through to login form" @@ -401,7 +401,7 @@ class SecurityTest extends FunctionalTest // Test external redirect $response = $this->doTestLoginForm('noexpiry@silverstripe.com', '1nitialPassword', 'http://myspoofedhost.com'); - $this->assertNotRegExp( + $this->assertDoesNotMatchRegularExpression( '/^' . preg_quote('http://myspoofedhost.com', '/') . '/', (string)$response->getHeader('Location'), "Redirection to external links in login form BackURL gets prevented as a measure against spoofing attacks" @@ -410,7 +410,7 @@ class SecurityTest extends FunctionalTest // Test external redirection on ChangePasswordForm $this->get('Security/changepassword?BackURL=http://myspoofedhost.com'); $changedResponse = $this->doTestChangepasswordForm('1nitialPassword', 'changedPassword#123'); - $this->assertNotRegExp( + $this->assertDoesNotMatchRegularExpression( '/^' . preg_quote('http://myspoofedhost.com', '/') . '/', (string)$changedResponse->getHeader('Location'), "Redirection to external links in change password form BackURL gets prevented to stop spoofing attacks" @@ -428,7 +428,7 @@ class SecurityTest extends FunctionalTest /* BAD PASSWORDS ARE LOCKED OUT */ $badResponse = $this->doTestLoginForm('testuser@example.com', 'badpassword'); $this->assertEquals(302, $badResponse->getStatusCode()); - $this->assertRegExp('/Security\/login/', $badResponse->getHeader('Location')); + $this->assertMatchesRegularExpression('/Security\/login/', $badResponse->getHeader('Location')); $this->assertNull($this->session()->get('loggedInAs')); /* UNEXPIRED PASSWORD GO THROUGH WITHOUT A HITCH */ @@ -714,7 +714,7 @@ class SecurityTest extends FunctionalTest $response = $this->get(Config::inst()->get(Security::class, 'login_url')); $robotsHeader = $response->getHeader('X-Robots-Tag'); $this->assertNotNull($robotsHeader); - $this->assertContains('noindex', $robotsHeader); + $this->assertStringContainsString('noindex', $robotsHeader); } public function testDoNotSendEmptyRobotsHeaderIfNotDefined() @@ -812,7 +812,7 @@ class SecurityTest extends FunctionalTest } } - $this->assertContains($expected, $messages, $errorMessage); + $this->assertContains($expected, $messages, $errorMessage ?: ''); } /** diff --git a/tests/php/Security/VersionedMemberAuthenticatorTest.php b/tests/php/Security/VersionedMemberAuthenticatorTest.php index eedbb90db..da1baac7c 100644 --- a/tests/php/Security/VersionedMemberAuthenticatorTest.php +++ b/tests/php/Security/VersionedMemberAuthenticatorTest.php @@ -36,7 +36,7 @@ class VersionedMemberAuthenticatorTest extends SapphireTest ] ]; - public function setUp() + protected function setUp(): void { parent::setUp(); @@ -51,7 +51,7 @@ class VersionedMemberAuthenticatorTest extends SapphireTest ->setTestNames([]); } - protected function tearDown() + protected function tearDown(): void { $this->logOut(); parent::tearDown(); diff --git a/tests/php/View/ArrayDataTest.php b/tests/php/View/ArrayDataTest.php index b60729711..b90258f79 100644 --- a/tests/php/View/ArrayDataTest.php +++ b/tests/php/View/ArrayDataTest.php @@ -53,14 +53,6 @@ class ArrayDataTest extends SapphireTest { $array = [0 => "One", 1 => "Two"]; $this->assertFalse(ArrayLib::is_associative($array)); - - /* - * Expect user_error() to be called below, if enabled - * (tobych) That should be an exception. Something like: - * $this->setExpectedException('InvalidArgumentException'); - */ - - // $arrayData = new ArrayData($array); } public function testSetField() diff --git a/tests/php/View/ContentNegotiatorTest.php b/tests/php/View/ContentNegotiatorTest.php index c1cbfbb78..7465e55fa 100644 --- a/tests/php/View/ContentNegotiatorTest.php +++ b/tests/php/View/ContentNegotiatorTest.php @@ -60,21 +60,21 @@ class ContentNegotiatorTest extends SapphireTest //////////////////////// // XHTML select options //////////////////////// - $this->assertRegExp('/