1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 * @author Daniel Kinzler
20 */
21
22use MediaWiki\Page\PageIdentity;
23use MediaWiki\Page\PageIdentityValue;
24
25/**
26 * @covers TitleValue
27 *
28 * @group Title
29 */
30class TitleValueTest extends \MediaWikiUnitTestCase {
31
32	public function goodConstructorProvider() {
33		return [
34			[ NS_MAIN, '', 'fragment', '', true, false ],
35			[ NS_MAIN, '', '', 'interwiki', false, true ],
36			[ NS_MAIN, '', 'fragment', 'interwiki', true, true ],
37			[ NS_USER, 'TestThis', 'stuff', '', true, false ],
38			[ NS_USER, 'TestThis', '', 'baz', false, true ],
39			[ NS_MAIN, 'foo bar', '', '', false, false ],
40			[ NS_MAIN, 'foo_bar', '', '', false, false ],
41			[ NS_MAIN, '', '', '', false, false ],
42		];
43	}
44
45	/**
46	 * @dataProvider goodConstructorProvider
47	 */
48	public function testConstruction( $ns, $text, $fragment, $interwiki, $hasFragment,
49		$hasInterwiki
50	) {
51		$title = new TitleValue( $ns, $text, $fragment, $interwiki );
52
53		$this->assertEquals( $ns, $title->getNamespace() );
54		$this->assertTrue( $title->inNamespace( $ns ) );
55		$this->assertEquals( strtr( $text, ' ', '_' ), $title->getDBKey() );
56		$this->assertEquals( strtr( $text, '_', ' ' ), $title->getText() );
57		$this->assertEquals( $fragment, $title->getFragment() );
58		$this->assertEquals( $hasFragment, $title->hasFragment() );
59		$this->assertEquals( $interwiki, $title->getInterwiki() );
60		$this->assertEquals( $hasInterwiki, $title->isExternal() );
61	}
62
63	/**
64	 * @dataProvider goodConstructorProvider
65	 */
66	public function testTryNew( $ns, $text, $fragment, $interwiki, $hasFragment,
67		$hasInterwiki
68	) {
69		$title = TitleValue::tryNew( $ns, $text, $fragment, $interwiki );
70
71		$this->assertEquals( $ns, $title->getNamespace() );
72		$this->assertTrue( $title->inNamespace( $ns ) );
73		$this->assertEquals( strtr( $text, ' ', '_' ), $title->getDBKey() );
74		$this->assertEquals( strtr( $text, '_', ' ' ), $title->getText() );
75		$this->assertEquals( $fragment, $title->getFragment() );
76		$this->assertEquals( $hasFragment, $title->hasFragment() );
77		$this->assertEquals( $interwiki, $title->getInterwiki() );
78		$this->assertEquals( $hasInterwiki, $title->isExternal() );
79	}
80
81	/**
82	 * @dataProvider goodConstructorProvider
83	 */
84	public function testAssertValidSpec( $ns, $text, $fragment, $interwiki ) {
85		TitleValue::assertValidSpec( $ns, $text, $fragment, $interwiki );
86		$this->assertTrue( true ); // we are just checking that no exception is thrown
87	}
88
89	public function badConstructorNamespaceTypeProvider() {
90		return [
91			[ 'foo', 'title', 'fragment', '' ],
92			[ null, 'title', 'fragment', '' ],
93			[ 2.3, 'title', 'fragment', '' ],
94		];
95	}
96
97	public function badConstructorProvider() {
98		return [
99			[ NS_MAIN, 5, 'fragment', '' ],
100			[ NS_MAIN, null, 'fragment', '' ],
101			[ NS_USER, '', 'fragment', '' ],
102			[ NS_USER, '', '', 'interwiki' ],
103			[ NS_MAIN, 'bar_', '', '' ],
104			[ NS_MAIN, '_foo', '', '' ],
105			[ NS_MAIN, ' eek ', '', '' ],
106
107			[ NS_MAIN, 'title', 5, '' ],
108			[ NS_MAIN, 'title', null, '' ],
109			[ NS_MAIN, 'title', [], '' ],
110
111			[ NS_MAIN, 'title', '', 5 ],
112			[ NS_MAIN, 'title', null, 5 ],
113			[ NS_MAIN, 'title', [], 5 ],
114		];
115	}
116
117	/**
118	 * @dataProvider badConstructorNamespaceTypeProvider
119	 * @dataProvider badConstructorProvider
120	 */
121	public function testConstructionErrors( $ns, $text, $fragment, $interwiki ) {
122		$this->expectException( InvalidArgumentException::class );
123		new TitleValue( $ns, $text, $fragment, $interwiki );
124	}
125
126	/**
127	 * @dataProvider badConstructorNamespaceTypeProvider
128	 */
129	public function testTryNewErrors( $ns, $text, $fragment, $interwiki ) {
130		$this->expectException( InvalidArgumentException::class );
131		TitleValue::tryNew( $ns, $text, $fragment, $interwiki );
132	}
133
134	/**
135	 * @dataProvider badConstructorProvider
136	 */
137	public function testTryNewFailure( $ns, $text, $fragment, $interwiki ) {
138		$this->assertNull( TitleValue::tryNew( $ns, $text, $fragment, $interwiki ) );
139	}
140
141	/**
142	 * @dataProvider badConstructorProvider
143	 */
144	public function testAssertValidSpecErrors( $ns, $text, $fragment, $interwiki ) {
145		$this->expectException( InvalidArgumentException::class );
146		TitleValue::assertValidSpec( $ns, $text, $fragment, $interwiki );
147	}
148
149	public function fragmentTitleProvider() {
150		return [
151			[ new TitleValue( NS_MAIN, 'Test' ), 'foo' ],
152			[ new TitleValue( NS_TALK, 'Test', 'foo' ), '' ],
153			[ new TitleValue( NS_CATEGORY, 'Test', 'foo' ), 'bar' ],
154		];
155	}
156
157	/**
158	 * @dataProvider fragmentTitleProvider
159	 */
160	public function testCreateFragmentTitle( TitleValue $title, $fragment ) {
161		$fragmentTitle = $title->createFragmentTarget( $fragment );
162
163		$this->assertEquals( $title->getNamespace(), $fragmentTitle->getNamespace() );
164		$this->assertEquals( $title->getText(), $fragmentTitle->getText() );
165		$this->assertEquals( $fragment, $fragmentTitle->getFragment() );
166	}
167
168	public function testNewFromPage() {
169		$page = new PageIdentityValue( 0, NS_USER, 'Test', PageIdentity::LOCAL );
170		$title = TitleValue::newFromPage( $page );
171
172		$this->assertSame( NS_USER, $title->getNamespace() );
173		$this->assertSame( 'Test', $title->getDBkey() );
174		$this->assertSame( 'Test', $title->getText() );
175		$this->assertSame( '', $title->getFragment() );
176		$this->assertSame( '', $title->getInterwiki() );
177		$this->assertFalse( $title->isExternal() );
178	}
179
180	public function getTextProvider() {
181		return [
182			[ 'Foo', 'Foo' ],
183			[ 'Foo_Bar', 'Foo Bar' ],
184		];
185	}
186
187	/**
188	 * @dataProvider getTextProvider
189	 */
190	public function testGetText( $dbkey, $text ) {
191		$title = new TitleValue( NS_MAIN, $dbkey );
192
193		$this->assertEquals( $text, $title->getText() );
194	}
195
196	public function provideTestToString() {
197		yield [
198			new TitleValue( 0, 'Foo' ),
199			'0:Foo'
200		];
201		yield [
202			new TitleValue( 1, 'Bar_Baz' ),
203			'1:Bar_Baz'
204		];
205		yield [
206			new TitleValue( 9, 'JoJo', 'Frag' ),
207			'9:JoJo#Frag'
208		];
209		yield [
210			new TitleValue( 200, 'tea', 'Fragment', 'wikicode' ),
211			'wikicode:200:tea#Fragment'
212		];
213	}
214
215	/**
216	 * @dataProvider provideTestToString
217	 */
218	public function testToString( TitleValue $value, $expected ) {
219		$this->assertSame(
220			$expected,
221			$value->__toString()
222		);
223	}
224
225	public function provideIsSameLinkAs() {
226		yield [
227			new TitleValue( 0, 'Foo' ),
228			new TitleValue( 0, 'Foo' ),
229			true
230		];
231		yield [
232			new TitleValue( 1, 'Bar_Baz' ),
233			new TitleValue( 1, 'Bar_Baz' ),
234			true
235		];
236		yield [
237			new TitleValue( 0, 'Foo' ),
238			new TitleValue( 1, 'Foo' ),
239			false
240		];
241		yield [
242			new TitleValue( 0, 'Foo' ),
243			new TitleValue( 0, 'Foozz' ),
244			false
245		];
246		yield [
247			new TitleValue( 0, 'Foo', '' ),
248			new TitleValue( 0, 'Foo', 'Bar' ),
249			false
250		];
251		yield [
252			new TitleValue( 0, 'Foo', '', 'bar' ),
253			new TitleValue( 0, 'Foo', '', '' ),
254			false
255		];
256	}
257
258	/**
259	 * @dataProvider provideIsSameLinkAs
260	 */
261	public function testIsSameLinkAs( TitleValue $a, TitleValue $b, $expected ) {
262		$this->assertSame( $expected, $a->isSameLinkAs( $b ) );
263		$this->assertSame( $expected, $b->isSameLinkAs( $a ) );
264	}
265}
266