X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=tests%2Fphpunit%2FMediaWikiTestCase.php;h=486b16de85c5edb12e918f9f2f06082f45a0d950;hb=9dcd12714e1dd761a62d68520ea6f4a370b4b735;hp=ebc3b79c3fffd39111cc18b0963adeea82190008;hpb=ad83e01f61aef535f7b0451bf74277d774c52d3b;p=lhc%2Fweb%2Fwiklou.git diff --git a/tests/phpunit/MediaWikiTestCase.php b/tests/phpunit/MediaWikiTestCase.php index ebc3b79c3f..486b16de85 100644 --- a/tests/phpunit/MediaWikiTestCase.php +++ b/tests/phpunit/MediaWikiTestCase.php @@ -472,7 +472,17 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase { * @return string Absolute name of the temporary file */ protected function getNewTempFile() { - $fileName = tempnam( wfTempDir(), 'MW_PHPUnit_' . static::class . '_' ); + $fileName = tempnam( + wfTempDir(), + // Avoid backslashes here as they result in inconsistent results + // between Windows and other OS, as well as between functions + // that try to normalise these in one or both directions. + // For example, tempnam rejects directory separators in the prefix which + // means it rejects any namespaced class on Windows. + // And then there is, wfMkdirParents which normalises paths always + // whereas most other PHP and MW functions do not. + 'MW_PHPUnit_' . strtr( static::class, [ '\\' => '_' ] ) . '_' + ); $this->tmpFiles[] = $fileName; return $fileName; @@ -489,14 +499,15 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase { * @return string Absolute name of the temporary directory */ protected function getNewTempDirectory() { - // Starting of with a temporary /file/. + // Starting of with a temporary *file*. $fileName = $this->getNewTempFile(); - // Converting the temporary /file/ to a /directory/ + // Converting the temporary file to a *directory*. // The following is not atomic, but at least we now have a single place, - // where temporary directory creation is bundled and can be improved + // where temporary directory creation is bundled and can be improved. unlink( $fileName ); - $this->assertTrue( wfMkdirParents( $fileName ) ); + // If this fails for some reason, PHP will warn and fail the test. + mkdir( $fileName, 0777, /* recursive = */ true ); return $fileName; } @@ -806,29 +817,6 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase { return false; } - /** - * Stashes the global, will be restored in tearDown() - * - * Individual test functions may override globals through the setMwGlobals() function - * or directly. When directly overriding globals their keys should first be passed to this - * method in setUp to avoid breaking global state for other tests - * - * That way all other tests are executed with the same settings (instead of using the - * unreliable local settings for most tests and fix it only for some tests). - * - * @param array|string $globalKeys Key to the global variable, or an array of keys. - * - * @note To allow changes to global variables to take effect on global service instances, - * call overrideMwServices(). - * - * @since 1.23 - * @deprecated since 1.32, use setMwGlobals() and don't alter globals directly - */ - protected function stashMwGlobals( $globalKeys ) { - wfDeprecated( __METHOD__, '1.32' ); - $this->doStashMwGlobals( $globalKeys ); - } - private function doStashMwGlobals( $globalKeys ) { if ( is_string( $globalKeys ) ) { $globalKeys = [ $globalKeys ]; @@ -966,6 +954,8 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase { $newInstance->redefineService( $name, $callback ); } + self::resetGlobalParser(); + return $newInstance; } @@ -1030,6 +1020,9 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase { ); MediaWikiServices::forceGlobalInstance( $newServices ); + + self::resetGlobalParser(); + return $newServices; } @@ -1058,9 +1051,26 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase { MediaWikiServices::forceGlobalInstance( self::$originalServices ); $currentServices->destroy(); + self::resetGlobalParser(); + return true; } + /** + * If $wgParser has been unstubbed, replace it with a fresh one so it picks up any config + * changes. $wgParser is deprecated, but we still support it for now. + */ + private static function resetGlobalParser() { + // phpcs:ignore MediaWiki.Usage.DeprecatedGlobalVariables.Deprecated$wgParser + global $wgParser; + if ( $wgParser instanceof StubObject ) { + return; + } + $wgParser = new StubObject( 'wgParser', function () { + return MediaWikiServices::getInstance()->getParser(); + } ); + } + /** * @since 1.27 * @param string|Language $lang @@ -2233,18 +2243,19 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase { } // NOTE: prefer content namespaces + $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo(); $namespaces = array_unique( array_merge( - MWNamespace::getContentNamespaces(), + $nsInfo->getContentNamespaces(), [ NS_MAIN, NS_HELP, NS_PROJECT ], // prefer these - MWNamespace::getValidNamespaces() + $nsInfo->getValidNamespaces() ) ); $namespaces = array_diff( $namespaces, [ NS_FILE, NS_CATEGORY, NS_MEDIAWIKI, NS_USER // don't mess with magic namespaces ] ); - $talk = array_filter( $namespaces, function ( $ns ) { - return MWNamespace::isTalk( $ns ); + $talk = array_filter( $namespaces, function ( $ns ) use ( $nsInfo ) { + return $nsInfo->isTalk( $ns ); } ); // prefer non-talk pages @@ -2355,7 +2366,7 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase { if ( $createIfMissing ) { if ( !file_exists( $fileName ) ) { file_put_contents( $fileName, $actualData ); - $this->markTestSkipped( 'Data file $fileName does not exist' ); + $this->markTestSkipped( "Data file $fileName does not exist" ); } } else { self::assertFileExists( $fileName ); @@ -2408,4 +2419,18 @@ abstract class MediaWikiTestCase extends PHPUnit\Framework\TestCase { 'comment' => $comment, ] ); } + + /** + * Returns a PHPUnit constraint that matches anything other than a fixed set of values. This can + * be used to whitelist values, e.g. + * $mock->expects( $this->never() )->method( $this->anythingBut( 'foo', 'bar' ) ); + * which will throw if any unexpected method is called. + * + * @param mixed ...$values Values that are not matched + */ + protected function anythingBut( ...$values ) { + return $this->logicalNot( $this->logicalOr( + ...array_map( [ $this, 'matches' ], $values ) + ) ); + } }