Make TitleFormatter accept PageIdentity interface

Refactor TitleFormatter
- ::getText(),
- ::getPrefixedTest,
- ::getPrefixedDBkey,
- ::getFullText

and their implementation

Refactor tests for MediaWikiTitleCodec class

Bug: T278125
Change-Id: I629291575720cc36110be63efcec7d5be57244c1
This commit is contained in:
Vadim Kovalenko 2021-03-22 11:51:19 -04:00
parent 83a5f20d53
commit 6841c49dcf
3 changed files with 181 additions and 68 deletions

View file

@ -22,6 +22,7 @@
*/
use MediaWiki\Interwiki\InterwikiLookup;
use MediaWiki\Linker\LinkTarget;
use MediaWiki\Page\PageIdentity;
use Wikimedia\IPUtils;
/**
@ -212,64 +213,99 @@ class MediaWikiTitleCodec implements TitleFormatter, TitleParser {
/**
* @see TitleFormatter::getText()
*
* @param LinkTarget $title
* @param LinkTarget|PageIdentity $title
*
* @return string $title->getText()
* @return string
*/
public function getText( LinkTarget $title ) {
return $title->getText();
public function getText( $title ) {
if ( $title instanceof LinkTarget ) {
return $title->getText();
} elseif ( $title instanceof PageIdentity ) {
return strtr( $title->getDBKey(), '_', ' ' );
} else {
throw new InvalidArgumentException( '$title has invalid type: ' . get_class( $title ) );
}
}
/**
* @see TitleFormatter::getText()
*
* @param LinkTarget $title
* @param LinkTarget|PageIdentity $title
*
* @return string
* @suppress PhanUndeclaredProperty
*/
public function getPrefixedText( LinkTarget $title ) {
if ( !isset( $title->prefixedText ) ) {
$title->prefixedText = $this->formatTitle(
public function getPrefixedText( $title ) {
if ( $title instanceof LinkTarget ) {
if ( !isset( $title->prefixedText ) ) {
$title->prefixedText = $this->formatTitle(
$title->getNamespace(),
$title->getText(),
'',
$title->getInterwiki()
);
}
return $title->prefixedText;
} elseif ( $title instanceof PageIdentity ) {
$title->assertWiki( PageIdentity::LOCAL );
return $this->formatTitle(
$title->getNamespace(),
$title->getText(),
'',
$title->getInterwiki()
$this->getText( $title )
);
} else {
throw new InvalidArgumentException( '$title has invalid type: ' . get_class( $title ) );
}
return $title->prefixedText;
}
/**
* @since 1.27
* @see TitleFormatter::getPrefixedDBkey()
* @param LinkTarget $target
* @param LinkTarget|PageIdentity $target
* @return string
*/
public function getPrefixedDBkey( LinkTarget $target ) {
return strtr( $this->formatTitle(
$target->getNamespace(),
$target->getDBkey(),
'',
$target->getInterwiki()
), ' ', '_' );
public function getPrefixedDBkey( $target ) {
if ( $target instanceof LinkTarget ) {
return strtr( $this->formatTitle(
$target->getNamespace(),
$target->getDBkey(),
'',
$target->getInterwiki()
), ' ', '_' );
} elseif ( $target instanceof PageIdentity ) {
$target->assertWiki( PageIdentity::LOCAL );
return strtr( $this->formatTitle(
$target->getNamespace(),
$target->getDBkey()
), ' ', '_' );
} else {
throw new InvalidArgumentException( '$title has invalid type: ' . get_class( $target ) );
}
}
/**
* @see TitleFormatter::getText()
*
* @param LinkTarget $title
* @param LinkTarget|PageIdentity $title
*
* @return string
*/
public function getFullText( LinkTarget $title ) {
return $this->formatTitle(
$title->getNamespace(),
$title->getText(),
$title->getFragment(),
$title->getInterwiki()
);
public function getFullText( $title ) {
if ( $title instanceof LinkTarget ) {
return $this->formatTitle(
$title->getNamespace(),
$title->getText(),
$title->getFragment(),
$title->getInterwiki()
);
} elseif ( $title instanceof PageIdentity ) {
$title->assertWiki( PageIdentity::LOCAL );
return $this->formatTitle(
$title->getNamespace(),
$this->getText( $title )
);
} else {
throw new InvalidArgumentException( '$title has invalid type: ' . get_class( $title ) );
}
}
/**

View file

@ -21,6 +21,7 @@
* @author Daniel Kinzler
*/
use MediaWiki\Linker\LinkTarget;
use MediaWiki\Page\PageIdentity;
/**
* A title formatter service for MediaWiki.
@ -50,22 +51,20 @@ interface TitleFormatter {
/**
* Returns the title text formatted for display, without namespace of fragment.
*
* @note Consider using LinkTarget::getText() directly, it's identical.
*
* @param LinkTarget $title The title to format
* @param LinkTarget|PageIdentity $title The title to format
*
* @return string
*/
public function getText( LinkTarget $title );
public function getText( $title );
/**
* Returns the title formatted for display, including the namespace name.
*
* @param LinkTarget $title The title to format
* @param LinkTarget|PageIdentity $title The title to format
*
* @return string
*/
public function getPrefixedText( LinkTarget $title );
public function getPrefixedText( $title );
/**
* Return the title in prefixed database key form, with interwiki
@ -73,20 +72,20 @@ interface TitleFormatter {
*
* @since 1.27
*
* @param LinkTarget $target
* @param LinkTarget|PageIdentity $target
*
* @return string
*/
public function getPrefixedDBkey( LinkTarget $target );
public function getPrefixedDBkey( $target );
/**
* Returns the title formatted for display, with namespace and fragment.
*
* @param LinkTarget $title The title to format
* @param LinkTarget|PageIdentity $title The title to format
*
* @return string
*/
public function getFullText( LinkTarget $title );
public function getFullText( $title );
/**
* Returns the name of the namespace for the given title.

View file

@ -21,6 +21,8 @@
use MediaWiki\Interwiki\InterwikiLookup;
use MediaWiki\MediaWikiServices;
use MediaWiki\Page\PageIdentity;
use MediaWiki\Page\PageIdentityValue;
/**
* @covers MediaWikiTitleCodec
@ -197,19 +199,20 @@ class MediaWikiTitleCodecTest extends MediaWikiIntegrationTestCase {
}
public static function provideGetText() {
// $title = new TitleValue( $namespace, $dbkey, $fragment );
return [
[ NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ],
[ NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'Hansi Maier' ],
[ new TitleValue( NS_MAIN, 'Foo_Bar', '' ), 'en', 'Foo Bar' ],
[ new TitleValue( NS_USER, 'Hansi_Maier', 'stuff_and_so_on' ), 'en', 'Hansi Maier' ],
[ new PageIdentityValue( 37, NS_MAIN, 'Foo_Bar', PageIdentity::LOCAL ), 'en', 'Foo Bar' ],
[ new PageIdentityValue( 37, NS_USER, 'Hansi_Maier', PageIdentity::LOCAL ), 'en', 'Hansi Maier' ],
];
}
/**
* @dataProvider provideGetText
*/
public function testGetText( $namespace, $dbkey, $fragment, $lang, $expected ) {
public function testGetText( $title, $lang, $expected ) {
$codec = $this->makeCodec( $lang );
$title = new TitleValue( $namespace, $dbkey, $fragment );
$actual = $codec->getText( $title );
$this->assertEquals( $expected, $actual );
@ -217,26 +220,56 @@ class MediaWikiTitleCodecTest extends MediaWikiIntegrationTestCase {
public static function provideGetPrefixedText() {
return [
[ NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ],
[ NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'User:Hansi Maier' ],
[ new TitleValue( NS_MAIN, 'Foo_Bar', '' ), 'en', 'Foo Bar' ],
[ new TitleValue( NS_USER, 'Hansi_Maier', 'stuff_and_so_on' ), 'en', 'User:Hansi Maier' ],
// No capitalization or normalization is applied while formatting!
[ NS_USER_TALK, 'hansi__maier', '', 'en', 'User talk:hansi maier' ],
[ new TitleValue( NS_USER_TALK, 'hansi__maier', '' ), 'en', 'User talk:hansi maier' ],
// getGenderCache() provides a mock that considers first
// names ending in "a" to be female.
[ NS_USER, 'Lisa_Müller', '', 'de', 'Benutzerin:Lisa Müller' ],
[ 1000000, 'Invalid_namespace', '', 'en', 'Special:Badtitle/NS1000000:Invalid namespace' ],
[
new TitleValue( NS_USER, 'Lisa_Müller', '' ),
'de', 'Benutzerin:Lisa Müller'
],
[
new TitleValue( 1000000, 'Invalid_namespace', '' ),
'en',
'Special:Badtitle/NS1000000:Invalid namespace'
],
[
new PageIdentityValue( 37, NS_MAIN, 'Foo_Bar', PageIdentity::LOCAL ),
'en',
'Foo Bar'
],
[
new PageIdentityValue( 37, NS_USER, 'Hansi_Maier', PageIdentity::LOCAL ),
'en',
'User:Hansi Maier'
],
[
new PageIdentityValue( 37, NS_USER_TALK, 'hansi__maier', PageIdentity::LOCAL ),
'en',
'User talk:hansi maier'
],
[
new PageIdentityValue( 37, NS_USER, 'Lisa_Müller', PageIdentity::LOCAL ),
'de',
'Benutzerin:Lisa Müller'
],
[
new PageIdentityValue( 37, 1000000, 'Invalid_namespace', PageIdentity::LOCAL ),
'en',
'Special:Badtitle/NS1000000:Invalid namespace'
],
];
}
/**
* @dataProvider provideGetPrefixedText
*/
public function testGetPrefixedText( $namespace, $dbkey, $fragment, $lang, $expected ) {
public function testGetPrefixedText( $title, $lang, $expected ) {
$codec = $this->makeCodec( $lang );
$title = new TitleValue( $namespace, $dbkey, $fragment );
$actual = $codec->getPrefixedText( $title );
$this->assertEquals( $expected, $actual );
@ -244,32 +277,60 @@ class MediaWikiTitleCodecTest extends MediaWikiIntegrationTestCase {
public static function provideGetPrefixedDBkey() {
return [
[ NS_MAIN, 'Foo_Bar', '', '', 'en', 'Foo_Bar' ],
[ NS_USER, 'Hansi_Maier', 'stuff_and_so_on', '', 'en', 'User:Hansi_Maier' ],
[ new TitleValue( NS_MAIN, 'Foo_Bar', '', '' ), 'en', 'Foo_Bar' ],
[ new TitleValue( NS_USER, 'Hansi_Maier', 'stuff_and_so_on', '' ), 'en', 'User:Hansi_Maier' ],
// No capitalization or normalization is applied while formatting!
[ NS_USER_TALK, 'hansi__maier', '', '', 'en', 'User_talk:hansi__maier' ],
[ new TitleValue( NS_USER_TALK, 'hansi__maier', '', '' ), 'en', 'User_talk:hansi__maier' ],
// getGenderCache() provides a mock that considers first
// names ending in "a" to be female.
[ NS_USER, 'Lisa_Müller', '', '', 'de', 'Benutzerin:Lisa_Müller' ],
[ new TitleValue( NS_USER, 'Lisa_Müller', '', '' ), 'de', 'Benutzerin:Lisa_Müller' ],
[ NS_MAIN, 'Remote_page', '', 'remotetestiw', 'en', 'remotetestiw:Remote_page' ],
[ new TitleValue( NS_MAIN, 'Remote_page', '', 'remotetestiw' ), 'en', 'remotetestiw:Remote_page' ],
// non-existent namespace
[ 10000000, 'Foobar', '', '', 'en', 'Special:Badtitle/NS10000000:Foobar' ],
[ new TitleValue( 10000000, 'Foobar', '', '' ), 'en', 'Special:Badtitle/NS10000000:Foobar' ],
[
new PageIdentityValue( 37, NS_MAIN, 'Foo_Bar', PageIdentity::LOCAL ),
'en' ,
'Foo_Bar'
],
[
new PageIdentityValue( 37, NS_USER, 'Hansi_Maier', PageIdentity::LOCAL ),
'en',
'User:Hansi_Maier'
],
[
new PageIdentityValue( 37, NS_USER_TALK, 'hansi__maier', PageIdentity::LOCAL ),
'en',
'User_talk:hansi__maier'
],
[
new PageIdentityValue( 37, NS_USER, 'Lisa_Müller', PageIdentity::LOCAL ),
'de',
'Benutzerin:Lisa_Müller'
],
[
new PageIdentityValue( 37, NS_MAIN, 'Remote_page', PageIdentity::LOCAL ),
'en' ,
'Remote_page'
],
[
new PageIdentityValue( 37, 10000000, 'Foobar', PageIdentity::LOCAL ),
'en' ,
'Special:Badtitle/NS10000000:Foobar'
],
];
}
/**
* @dataProvider provideGetPrefixedDBkey
*/
public function testGetPrefixedDBkey( $namespace, $dbkey, $fragment,
$interwiki, $lang, $expected
public function testGetPrefixedDBkey( $title, $lang, $expected
) {
$codec = $this->makeCodec( $lang );
$title = new TitleValue( $namespace, $dbkey, $fragment, $interwiki );
$actual = $codec->getPrefixedDBkey( $title );
$this->assertEquals( $expected, $actual );
@ -277,21 +338,38 @@ class MediaWikiTitleCodecTest extends MediaWikiIntegrationTestCase {
public static function provideGetFullText() {
return [
[ NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ],
[ NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'User:Hansi Maier#stuff and so on' ],
[ new TitleValue( NS_MAIN, 'Foo_Bar', '' ), 'en', 'Foo Bar' ],
[ new TitleValue( NS_USER, 'Hansi_Maier', 'stuff_and_so_on' ), 'en', 'User:Hansi Maier#stuff and so on' ],
// No capitalization or normalization is applied while formatting!
[ NS_USER_TALK, 'hansi__maier', '', 'en', 'User talk:hansi maier' ],
[ new TitleValue( NS_USER_TALK, 'hansi__maier', '' ), 'en', 'User talk:hansi maier' ],
[ new TitleValue( NS_MAIN, 'Foo_Bar' ), 'en', 'Foo Bar' ],
[ new TitleValue( NS_USER, 'Hansi_Maier' ), 'en', 'User:Hansi Maier' ],
[
new PageIdentityValue( 37, NS_MAIN, 'Foo_Bar', PageIdentity::LOCAL ),
'en',
'Foo Bar'
],
[
new PageIdentityValue( 37, NS_USER, 'Hansi_Maier', PageIdentity::LOCAL ),
'en',
'User:Hansi Maier'
],
[
new PageIdentityValue( 37, NS_USER_TALK, 'hansi__maier', PageIdentity::LOCAL ),
'en',
'User talk:hansi maier'
],
];
}
/**
* @dataProvider provideGetFullText
*/
public function testGetFullText( $namespace, $dbkey, $fragment, $lang, $expected ) {
public function testGetFullText( $title, $lang, $expected ) {
$codec = $this->makeCodec( $lang );
$title = new TitleValue( $namespace, $dbkey, $fragment );
$actual = $codec->getFullText( $title );
$this->assertEquals( $expected, $actual );