From 69ef837f41b213a4956d3e0e66c33da161033920 Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Sun, 5 Aug 2018 16:00:56 +0300 Subject: [PATCH] Update MediaWikiTitleCodec to use NamespaceInfo Depends-On: I759cde50e42020699138d32431c27428737f700f Change-Id: I57d77754288449ec54b039802adae05d56fa5563 --- includes/ServiceWiring.php | 3 +- includes/title/MediaWikiTitleCodec.php | 23 +++++- tests/phpunit/includes/TitleTest.php | 7 +- .../ApiQueryRecentChangesIntegrationTest.php | 10 +-- .../api/ApiQueryWatchlistIntegrationTest.php | 10 +-- .../title/MediaWikiTitleCodecTest.php | 75 ++++++++++++++----- 6 files changed, 79 insertions(+), 49 deletions(-) diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 750c964830..e141087678 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -657,7 +657,8 @@ return [ $services->getContentLanguage(), $services->getGenderCache(), $services->getMainConfig()->get( 'LocalInterwikis' ), - $services->getInterwikiLookup() + $services->getInterwikiLookup(), + $services->getNamespaceInfo() ); }, diff --git a/includes/title/MediaWikiTitleCodec.php b/includes/title/MediaWikiTitleCodec.php index adbea89db7..14c8b5fb9a 100644 --- a/includes/title/MediaWikiTitleCodec.php +++ b/includes/title/MediaWikiTitleCodec.php @@ -56,20 +56,35 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser { */ protected $interwikiLookup; + /** + * @var NamespaceInfo + */ + protected $nsInfo; + /** * @param Language $language The language object to use for localizing namespace names. * @param GenderCache $genderCache The gender cache for generating gendered namespace names * @param string[]|string $localInterwikis * @param InterwikiLookup|null $interwikiLookup + * @param NamespaceInfo|null $nsInfo */ public function __construct( Language $language, GenderCache $genderCache, - $localInterwikis = [], $interwikiLookup = null + $localInterwikis = [], InterwikiLookup $interwikiLookup = null, + NamespaceInfo $nsInfo = null ) { + if ( !$interwikiLookup ) { + wfDeprecated( __METHOD__ . ' with no InterwikiLookup argument', '1.34' ); + $interwikiLookup = MediaWikiServices::getInstance()->getInterwikiLookup(); + } + if ( !$nsInfo ) { + wfDeprecated( __METHOD__ . ' with no NamespaceInfo argument', '1.34' ); + $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo(); + } $this->language = $language; $this->genderCache = $genderCache; $this->localInterwikis = (array)$localInterwikis; - $this->interwikiLookup = $interwikiLookup ?: - MediaWikiServices::getInstance()->getInterwikiLookup(); + $this->interwikiLookup = $interwikiLookup; + $this->nsInfo = $nsInfo; } /** @@ -83,7 +98,7 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser { */ public function getNamespaceName( $namespace, $text ) { if ( $this->language->needsGenderDistinction() && - MWNamespace::hasGenderDistinction( $namespace ) + $this->nsInfo->hasGenderDistinction( $namespace ) ) { // NOTE: we are assuming here that the title text is a user name! $gender = $this->genderCache->getGenderOf( $text, __METHOD__ ); diff --git a/tests/phpunit/includes/TitleTest.php b/tests/phpunit/includes/TitleTest.php index 149c25bc5f..f97654080d 100644 --- a/tests/phpunit/includes/TitleTest.php +++ b/tests/phpunit/includes/TitleTest.php @@ -150,12 +150,7 @@ class TitleTest extends MediaWikiTestCase { ] ] ); - // Reset TitleParser since we modified $wgLocalInterwikis - $this->setService( 'TitleParser', new MediaWikiTitleCodec( - Language::factory( 'en' ), - new GenderCache(), - [ 'localtestiw' ] - ) ); + $this->overrideMwServices(); } /** diff --git a/tests/phpunit/includes/api/ApiQueryRecentChangesIntegrationTest.php b/tests/phpunit/includes/api/ApiQueryRecentChangesIntegrationTest.php index a95d5c1c0b..ff0e2e69a8 100644 --- a/tests/phpunit/includes/api/ApiQueryRecentChangesIntegrationTest.php +++ b/tests/phpunit/includes/api/ApiQueryRecentChangesIntegrationTest.php @@ -149,16 +149,8 @@ class ApiQueryRecentChangesIntegrationTest extends ApiTestCase { return $response[0]['query']['recentchanges']; } - private function getTitleFormatter() { - return new MediaWikiTitleCodec( - Language::factory( 'en' ), - MediaWikiServices::getInstance()->getGenderCache() - ); - } - private function getPrefixedText( LinkTarget $target ) { - $formatter = $this->getTitleFormatter(); - return $formatter->getPrefixedText( $target ); + return MediaWikiServices::getInstance()->getTitleFormatter()->getPrefixedText( $target ); } public function testListRecentChanges_returnsRCInfo() { diff --git a/tests/phpunit/includes/api/ApiQueryWatchlistIntegrationTest.php b/tests/phpunit/includes/api/ApiQueryWatchlistIntegrationTest.php index 41ecd52944..2b08a81c2e 100644 --- a/tests/phpunit/includes/api/ApiQueryWatchlistIntegrationTest.php +++ b/tests/phpunit/includes/api/ApiQueryWatchlistIntegrationTest.php @@ -228,16 +228,8 @@ class ApiQueryWatchlistIntegrationTest extends ApiTestCase { } } - private function getTitleFormatter() { - return new MediaWikiTitleCodec( - Language::factory( 'en' ), - MediaWikiServices::getInstance()->getGenderCache() - ); - } - private function getPrefixedText( LinkTarget $target ) { - $formatter = $this->getTitleFormatter(); - return $formatter->getPrefixedText( $target ); + return MediaWikiServices::getInstance()->getTitleFormatter()->getPrefixedText( $target ); } private function cleanTestUsersWatchlist() { diff --git a/tests/phpunit/includes/title/MediaWikiTitleCodecTest.php b/tests/phpunit/includes/title/MediaWikiTitleCodecTest.php index 20f0039f57..0b573999ca 100644 --- a/tests/phpunit/includes/title/MediaWikiTitleCodecTest.php +++ b/tests/phpunit/includes/title/MediaWikiTitleCodecTest.php @@ -19,6 +19,8 @@ * @author Daniel Kinzler */ +use MediaWiki\Interwiki\InterwikiLookup; + /** * @covers MediaWikiTitleCodec * @@ -37,21 +39,6 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase { 'wgMetaNamespace' => 'Project', 'wgLocalInterwikis' => [ 'localtestiw' ], 'wgCapitalLinks' => true, - - // NOTE: this is why global state is evil. - // TODO: refactor access to the interwiki codes so it can be injected. - 'wgHooks' => [ - 'InterwikiLoadPrefix' => [ - function ( $prefix, &$data ) { - if ( $prefix === 'localtestiw' ) { - $data = [ 'iw_url' => 'localtestiw' ]; - } elseif ( $prefix === 'remotetestiw' ) { - $data = [ 'iw_url' => 'remotetestiw' ]; - } - return false; - } - ] - ] ] ); $this->setUserLang( 'en' ); $this->setContentLang( 'en' ); @@ -77,12 +64,60 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase { return $genderCache; } + /** + * Returns a mock InterwikiLookup that only has an isValidInterwiki() method, which recognizes + * 'localtestiw' and 'remotetestiw'. All other methods throw. + * + * @return InterwikiLookup + */ + private function getInterwikiLookup() : InterwikiLookup { + $iwLookup = $this->createMock( InterwikiLookup::class ); + + $iwLookup->expects( $this->any() ) + ->method( 'isValidInterwiki' ) + ->will( $this->returnCallback( function ( $prefix ) { + return $prefix === 'localtestiw' || $prefix === 'remotetestiw'; + } ) ); + + $iwLookup->expects( $this->never() ) + ->method( $this->callback( function ( $name ) { + return $name !== 'isValidInterwiki'; + } ) ); + + return $iwLookup; + } + + /** + * Returns a mock NamespaceInfo that has only a hasGenderDistinction() method, which assumes + * only NS_USER and NS_USER_TALK have a gender distinction. All other methods throw. + * + * @return NamespaceInfo + */ + private function getNamespaceInfo() : NamespaceInfo { + $nsInfo = $this->createMock( NamespaceInfo::class ); + + $nsInfo->expects( $this->any() ) + ->method( 'hasGenderDistinction' ) + ->will( $this->returnCallback( function ( $ns ) { + return $ns === NS_USER || $ns === NS_USER_TALK; + } ) ); + + $nsInfo->expects( $this->never() ) + ->method( $this->callback( function ( $name ) { + return $name !== 'hasGenderDistinction'; + } ) ); + + return $nsInfo; + } + protected function makeCodec( $lang ) { - $gender = $this->getGenderCache(); - $lang = Language::factory( $lang ); - // language object can came from cache, which does not respect test settings - $lang->resetNamespaces(); - return new MediaWikiTitleCodec( $lang, $gender ); + return new MediaWikiTitleCodec( + Language::factory( $lang ), + $this->getGenderCache(), + [], + $this->getInterwikiLookup(), + $this->getNamespaceInfo() + ); } public static function provideFormat() { -- 2.20.1