Define equality for PageIdentity and LinkTarget
Bug: T272420 Change-Id: I2e0eb21989e2d733088ab77d7461bf003c2905eb
This commit is contained in:
parent
5db4b26fb4
commit
10ccdb2281
8 changed files with 351 additions and 27 deletions
|
|
@ -3930,16 +3930,71 @@ class Title implements LinkTarget, PageIdentity, IDBAccessObject {
|
|||
}
|
||||
|
||||
/**
|
||||
* Compare with another title.
|
||||
* Compares with another Title.
|
||||
*
|
||||
* @param LinkTarget $title
|
||||
* A Title object is considered equal to another Title if it has the same text,
|
||||
* the same interwiki prefix, and the same namespace.
|
||||
*
|
||||
* @note This is different from isSameLinkAs(), which also compares the fragment part,
|
||||
* and from isSamePageAs(), which takes into account the page ID.
|
||||
*
|
||||
* @phpcs:disable MediaWiki.Commenting.FunctionComment.ObjectTypeHintParam
|
||||
* @param object $other
|
||||
*
|
||||
* @return bool true if $other is a Title and refers to the same page.
|
||||
*/
|
||||
public function equals( object $other ) {
|
||||
if ( $other instanceof Title ) {
|
||||
// NOTE: In contrast to isSameLinkAs(), this ignores the fragment part!
|
||||
// NOTE: In contrast to isSamePageAs(), this ignores the page ID!
|
||||
// NOTE: === is necessary for proper matching of number-like titles
|
||||
return $this->getInterwiki() === $other->getInterwiki()
|
||||
&& $this->getNamespace() === $other->getNamespace()
|
||||
&& $this->getDBkey() === $other->getDBkey();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see LinkTarget::isSameLinkAs()
|
||||
* @since 1.36
|
||||
*
|
||||
* @param LinkTarget $other
|
||||
* @return bool
|
||||
*/
|
||||
public function equals( LinkTarget $title ) {
|
||||
// Note: === is necessary for proper matching of number-like titles.
|
||||
return $this->mInterwiki === $title->getInterwiki()
|
||||
&& $this->mNamespace == $title->getNamespace()
|
||||
&& $this->mDbkeyform === $title->getDBkey();
|
||||
public function isSameLinkAs( LinkTarget $other ) {
|
||||
// NOTE: keep in sync with TitleValue::isSameLinkAs()!
|
||||
// NOTE: === is needed for number-like titles
|
||||
return ( $other->getInterwiki() === $this->getInterwiki() )
|
||||
&& ( $other->getDBkey() === $this->getDBkey() )
|
||||
&& ( $other->getNamespace() === $this->getNamespace() )
|
||||
&& ( $other->getFragment() === $this->getFragment() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PageIdentity::isSamePageAs()
|
||||
* @since 1.36
|
||||
*
|
||||
* @param PageIdentity $other
|
||||
* @return bool
|
||||
*/
|
||||
public function isSamePageAs( PageIdentity $other ) {
|
||||
// NOTE: keep in sync with PageIdentityValue::isSamePageAs()!
|
||||
|
||||
if ( $other->getWikiId() !== $this->getWikiId()
|
||||
|| $other->getId() !== $this->getId() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->getId() === 0 ) {
|
||||
if ( $other->getNamespace() !== $this->getNamespace()
|
||||
|| $other->getDBkey() !== $this->getDBkey() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -104,10 +104,21 @@ interface LinkTarget {
|
|||
public function getInterwiki();
|
||||
|
||||
/**
|
||||
* Returns an informative human readable representation of the link target,
|
||||
* for use in logging and debugging. There is no requirement for the return
|
||||
* value to have any relationship with the input of TitleParser.
|
||||
* @since 1.31
|
||||
* Checks whether the given LinkTarget refers to the same target as this LinkTarget.
|
||||
*
|
||||
* Two link targets are considered the same if they have the same interwiki prefix,
|
||||
* the same namespace ID, the same text, and the same fragment.
|
||||
*
|
||||
* @since 1.36
|
||||
*
|
||||
* @param LinkTarget $other
|
||||
* @return bool
|
||||
*/
|
||||
public function isSameLinkAs( LinkTarget $other );
|
||||
|
||||
/**
|
||||
* Returns an informative human readable representation of the page identity,
|
||||
* for use in logging and debugging.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -183,6 +183,20 @@ interface PageIdentity {
|
|||
*/
|
||||
public function getDBkey(): string;
|
||||
|
||||
/**
|
||||
* Checks whether the given PageIdentity refers to the same page as this PageIdentity.
|
||||
*
|
||||
* Two PageIdentity instances are considered to refer to the same page if
|
||||
* the page exists, they belong to the same wiki, and have the same ID;
|
||||
* or the page does not exist, they belong to the same wiki, and have the
|
||||
* same namespace and DB key.
|
||||
*
|
||||
* @param PageIdentity $other
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSamePageAs( PageIdentity $other );
|
||||
|
||||
/**
|
||||
* Returns an informative human readable representation of the page identity,
|
||||
* for use in logging and debugging.
|
||||
|
|
|
|||
|
|
@ -182,4 +182,29 @@ class PageIdentityValue implements ProperPageIdentity {
|
|||
|
||||
return $name . ' [' . $this->namespace . ':' . $this->dbKey . ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PageIdentity $other
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSamePageAs( PageIdentity $other ) {
|
||||
// NOTE: keep in sync with Title::isSamePageAs()!
|
||||
// NOTE: keep in sync with WikiPage::isSamePageAs()!
|
||||
|
||||
if ( $other->getWikiId() !== $this->getWikiId()
|
||||
|| $other->getId() !== $this->getId() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->getId() === 0 ) {
|
||||
if ( $other->getNamespace() !== $this->getNamespace()
|
||||
|| $other->getDBkey() !== $this->getDBkey() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -315,4 +315,17 @@ class TitleValue implements LinkTarget {
|
|||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param LinkTarget $other
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSameLinkAs( LinkTarget $other ) {
|
||||
// NOTE: keep in sync with Title::isSameLinkAs()!
|
||||
return ( $other->getInterwiki() === $this->getInterwiki() )
|
||||
&& ( $other->getDBkey() === $this->getDBkey() )
|
||||
&& ( $other->getNamespace() === $this->getNamespace() )
|
||||
&& ( $other->getFragment() === $this->getFragment() );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ use MediaWiki\Interwiki\InterwikiLookup;
|
|||
use MediaWiki\Linker\LinkTarget;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Page\PageIdentity;
|
||||
use MediaWiki\Page\PageIdentityValue;
|
||||
use MediaWiki\User\UserIdentityValue;
|
||||
|
||||
/**
|
||||
* @group Database
|
||||
|
|
@ -1243,94 +1245,216 @@ class TitleTest extends MediaWikiIntegrationTestCase {
|
|||
}
|
||||
|
||||
public function provideEquals() {
|
||||
yield [
|
||||
yield '(newFromText) same text' => [
|
||||
Title::newFromText( 'Main Page' ),
|
||||
Title::newFromText( 'Main Page' ),
|
||||
true
|
||||
];
|
||||
yield [
|
||||
yield '(newFromText) different text' => [
|
||||
Title::newFromText( 'Main Page' ),
|
||||
Title::newFromText( 'Not The Main Page' ),
|
||||
false
|
||||
];
|
||||
yield [
|
||||
yield '(newFromText) different namespace, same text' => [
|
||||
Title::newFromText( 'Main Page' ),
|
||||
Title::newFromText( 'Project:Main Page' ),
|
||||
false
|
||||
];
|
||||
yield [
|
||||
yield '(newFromText) namespace alias' => [
|
||||
Title::newFromText( 'File:Example.png' ),
|
||||
Title::newFromText( 'Image:Example.png' ),
|
||||
true
|
||||
];
|
||||
yield [
|
||||
yield '(newFromText) same special page' => [
|
||||
Title::newFromText( 'Special:Version' ),
|
||||
Title::newFromText( 'Special:Version' ),
|
||||
true
|
||||
];
|
||||
yield [
|
||||
yield '(newFromText) different special page' => [
|
||||
Title::newFromText( 'Special:Version' ),
|
||||
Title::newFromText( 'Special:Recentchanges' ),
|
||||
false
|
||||
];
|
||||
yield [
|
||||
yield '(newFromText) compare special and normal page' => [
|
||||
Title::newFromText( 'Special:Version' ),
|
||||
Title::newFromText( 'Main Page' ),
|
||||
false
|
||||
];
|
||||
yield [
|
||||
yield '(makeTitle) same text' => [
|
||||
Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
|
||||
Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
|
||||
true
|
||||
];
|
||||
yield [
|
||||
yield '(makeTitle) different text' => [
|
||||
Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
|
||||
Title::makeTitle( NS_MAIN, 'Bar', '', '' ),
|
||||
false
|
||||
];
|
||||
yield [
|
||||
yield '(makeTitle) different namespace, same text' => [
|
||||
Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
|
||||
Title::makeTitle( NS_TALK, 'Foo', '', '' ),
|
||||
false
|
||||
];
|
||||
yield [
|
||||
yield '(makeTitle) same fragment' => [
|
||||
Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
|
||||
Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
|
||||
true
|
||||
];
|
||||
yield [
|
||||
yield '(makeTitle) different fragment (ignored)' => [
|
||||
Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
|
||||
Title::makeTitle( NS_MAIN, 'Foo', 'Baz', '' ),
|
||||
true
|
||||
];
|
||||
yield [
|
||||
yield '(makeTitle) fragment vs no fragment (ignored)' => [
|
||||
Title::makeTitle( NS_MAIN, 'Foo', 'Bar', '' ),
|
||||
Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
|
||||
true
|
||||
];
|
||||
yield [
|
||||
yield '(makeTitle) same interwiki' => [
|
||||
Title::makeTitle( NS_MAIN, 'Foo', '', 'baz' ),
|
||||
Title::makeTitle( NS_MAIN, 'Foo', '', 'baz' ),
|
||||
true
|
||||
];
|
||||
yield [
|
||||
yield '(makeTitle) different interwiki' => [
|
||||
Title::makeTitle( NS_MAIN, 'Foo', '', '' ),
|
||||
Title::makeTitle( NS_MAIN, 'Foo', '', 'baz' ),
|
||||
false
|
||||
];
|
||||
|
||||
// Wrong type
|
||||
yield '(makeTitle vs PageIdentityValue) name text' => [
|
||||
Title::makeTitle( NS_MAIN, 'Foo' ),
|
||||
new PageIdentityValue( 0, NS_MAIN, 'Foo', PageIdentity::LOCAL ),
|
||||
false
|
||||
];
|
||||
yield '(makeTitle vs TitleValue) name text' => [
|
||||
Title::makeTitle( NS_MAIN, 'Foo' ),
|
||||
new TitleValue( NS_MAIN, 'Foo' ),
|
||||
false
|
||||
];
|
||||
yield '(makeTitle vs UserIdentityValue) name text' => [
|
||||
Title::makeTitle( NS_MAIN, 'Foo' ),
|
||||
new UserIdentityValue( 7, 'Foo', 8 ),
|
||||
false
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Title::equals
|
||||
* @dataProvider provideEquals
|
||||
*/
|
||||
public function testEquals( Title $firstValue, /* LinkTarget */ $secondValue, $expectedSame ) {
|
||||
public function testEquals( Title $firstValue, $secondValue, $expectedSame ) {
|
||||
$this->assertSame(
|
||||
$expectedSame,
|
||||
$firstValue->equals( $secondValue )
|
||||
);
|
||||
}
|
||||
|
||||
public function provideIsSamePageAs() {
|
||||
$title = Title::makeTitle( 0, 'Foo' );
|
||||
$title->resetArticleID( 1 );
|
||||
yield '(PageIdentityValue) same text, title has ID 0' => [
|
||||
$title,
|
||||
new PageIdentityValue( 1, 0, 'Foo', PageIdentity::LOCAL ),
|
||||
true
|
||||
];
|
||||
|
||||
$title = Title::makeTitle( 1, 'Bar_Baz' );
|
||||
$title->resetArticleID( 0 );
|
||||
yield '(PageIdentityValue) same text, PageIdentityValue has ID 0' => [
|
||||
$title,
|
||||
new PageIdentityValue( 0, 1, 'Bar_Baz', PageIdentity::LOCAL ),
|
||||
true
|
||||
];
|
||||
|
||||
$title = Title::makeTitle( 0, 'Foo' );
|
||||
$title->resetArticleID( 0 );
|
||||
yield '(PageIdentityValue) different text, both IDs are 0' => [
|
||||
$title,
|
||||
new PageIdentityValue( 0, 0, 'Foozz', PageIdentity::LOCAL ),
|
||||
false
|
||||
];
|
||||
|
||||
$title = Title::makeTitle( 0, 'Foo' );
|
||||
$title->resetArticleID( 0 );
|
||||
yield '(PageIdentityValue) different namespace' => [
|
||||
$title,
|
||||
new PageIdentityValue( 0, 1, 'Foo', PageIdentity::LOCAL ),
|
||||
false
|
||||
];
|
||||
|
||||
$title = Title::makeTitle( 0, 'Foo', '' );
|
||||
$title->resetArticleID( 1 );
|
||||
yield '(PageIdentityValue) different wiki, different ID' => [
|
||||
$title,
|
||||
new PageIdentityValue( 1, 0, 'Foo', 'bar' ),
|
||||
false
|
||||
];
|
||||
|
||||
$title = Title::makeTitle( 0, 'Foo', '' );
|
||||
$title->resetArticleID( 0 );
|
||||
yield '(PageIdentityValue) different wiki, both IDs are 0' => [
|
||||
$title,
|
||||
new PageIdentityValue( 0, 0, 'Foo', 'bar' ),
|
||||
false
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Title::isSamePageAs
|
||||
* @dataProvider provideIsSamePageAs
|
||||
*/
|
||||
public function testIsSamePageAs( Title $firstValue, $secondValue, $expectedSame ) {
|
||||
$this->assertSame(
|
||||
$expectedSame,
|
||||
$firstValue->isSamePageAs( $secondValue )
|
||||
);
|
||||
}
|
||||
|
||||
public function provideIsSameLinkAs() {
|
||||
yield 'same text' => [
|
||||
Title::makeTitle( 0, 'Foo' ),
|
||||
new TitleValue( 0, 'Foo' ),
|
||||
true
|
||||
];
|
||||
yield 'same namespace' => [
|
||||
Title::makeTitle( 1, 'Bar_Baz' ),
|
||||
new TitleValue( 1, 'Bar_Baz' ),
|
||||
true
|
||||
];
|
||||
yield 'same text, different namespace' => [
|
||||
Title::makeTitle( 0, 'Foo' ),
|
||||
new TitleValue( 1, 'Foo' ),
|
||||
false
|
||||
];
|
||||
yield 'different text' => [
|
||||
Title::makeTitle( 0, 'Foo' ),
|
||||
new TitleValue( 0, 'Foozz' ),
|
||||
false
|
||||
];
|
||||
yield 'different fragment' => [
|
||||
Title::makeTitle( 0, 'Foo', '' ),
|
||||
new TitleValue( 0, 'Foo', 'Bar' ),
|
||||
false
|
||||
];
|
||||
yield 'different interwiki' => [
|
||||
Title::makeTitle( 0, 'Foo', '', 'bar' ),
|
||||
new TitleValue( 0, 'Foo', '', '' ),
|
||||
false
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Title::isSameLinkAs
|
||||
* @dataProvider provideIsSameLinkAs
|
||||
*/
|
||||
public function testIsSameLinkAs( Title $firstValue, $secondValue, $expectedSame ) {
|
||||
$this->assertSame(
|
||||
$expectedSame,
|
||||
$firstValue->isSameLinkAs( $secondValue )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Title::newMainPage
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -104,4 +104,45 @@ class PageIdentityValueTest extends MediaWikiUnitTestCase {
|
|||
$value->__toString()
|
||||
);
|
||||
}
|
||||
|
||||
public function provideIsSamePageAs() {
|
||||
yield [
|
||||
new PageIdentityValue( 1, 0, 'Foo', PageIdentity::LOCAL ),
|
||||
new PageIdentityValue( 1, 0, 'Foo', PageIdentity::LOCAL ),
|
||||
true
|
||||
];
|
||||
yield [
|
||||
new PageIdentityValue( 0, 1, 'Bar_Baz', PageIdentity::LOCAL ),
|
||||
new PageIdentityValue( 0, 1, 'Bar_Baz', PageIdentity::LOCAL ),
|
||||
true
|
||||
];
|
||||
yield [
|
||||
new PageIdentityValue( 0, 0, 'Foo', PageIdentity::LOCAL ),
|
||||
new PageIdentityValue( 0, 0, 'Foozz', PageIdentity::LOCAL ),
|
||||
false
|
||||
];
|
||||
yield [
|
||||
new PageIdentityValue( 0, 0, 'Foo', PageIdentity::LOCAL ),
|
||||
new PageIdentityValue( 0, 1, 'Foo', PageIdentity::LOCAL ),
|
||||
false
|
||||
];
|
||||
yield [
|
||||
new PageIdentityValue( 1, 0, 'Foo', '' ),
|
||||
new PageIdentityValue( 1, 0, 'Foo', 'bar' ),
|
||||
false
|
||||
];
|
||||
yield [
|
||||
new PageIdentityValue( 0, 0, 'Foo', '' ),
|
||||
new PageIdentityValue( 0, 0, 'Foo', 'bar' ),
|
||||
false
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideIsSamePageAs
|
||||
*/
|
||||
public function testIsSamePageAs( PageIdentityValue $a, PageIdentityValue $b, $expected ) {
|
||||
$this->assertSame( $expected, $a->isSamePageAs( $b ) );
|
||||
$this->assertSame( $expected, $b->isSamePageAs( $a ) );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -221,4 +221,45 @@ class TitleValueTest extends \MediaWikiUnitTestCase {
|
|||
$value->__toString()
|
||||
);
|
||||
}
|
||||
|
||||
public function provideIsSameLinkAs() {
|
||||
yield [
|
||||
new TitleValue( 0, 'Foo' ),
|
||||
new TitleValue( 0, 'Foo' ),
|
||||
true
|
||||
];
|
||||
yield [
|
||||
new TitleValue( 1, 'Bar_Baz' ),
|
||||
new TitleValue( 1, 'Bar_Baz' ),
|
||||
true
|
||||
];
|
||||
yield [
|
||||
new TitleValue( 0, 'Foo' ),
|
||||
new TitleValue( 1, 'Foo' ),
|
||||
false
|
||||
];
|
||||
yield [
|
||||
new TitleValue( 0, 'Foo' ),
|
||||
new TitleValue( 0, 'Foozz' ),
|
||||
false
|
||||
];
|
||||
yield [
|
||||
new TitleValue( 0, 'Foo', '' ),
|
||||
new TitleValue( 0, 'Foo', 'Bar' ),
|
||||
false
|
||||
];
|
||||
yield [
|
||||
new TitleValue( 0, 'Foo', '', 'bar' ),
|
||||
new TitleValue( 0, 'Foo', '', '' ),
|
||||
false
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideIsSameLinkAs
|
||||
*/
|
||||
public function testIsSameLinkAs( TitleValue $a, TitleValue $b, $expected ) {
|
||||
$this->assertSame( $expected, $a->isSameLinkAs( $b ) );
|
||||
$this->assertSame( $expected, $b->isSameLinkAs( $a ) );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue