Merge "Added letter Kra (ΔΈ) to special characters toolbar"
[lhc/web/wiklou.git] / tests / phpunit / includes / parser / ParserOutputTest.php
1 <?php
2
3 use Wikimedia\TestingAccessWrapper;
4
5 /**
6 * @group Database
7 * ^--- trigger DB shadowing because we are using Title magic
8 */
9 class ParserOutputTest extends MediaWikiTestCase {
10
11 public static function provideIsLinkInternal() {
12 return [
13 // Different domains
14 [ false, 'http://example.org', 'http://mediawiki.org' ],
15 // Same domains
16 [ true, 'http://example.org', 'http://example.org' ],
17 [ true, 'https://example.org', 'https://example.org' ],
18 [ true, '//example.org', '//example.org' ],
19 // Same domain different cases
20 [ true, 'http://example.org', 'http://EXAMPLE.ORG' ],
21 // Paths, queries, and fragments are not relevant
22 [ true, 'http://example.org', 'http://example.org/wiki/Main_Page' ],
23 [ true, 'http://example.org', 'http://example.org?my=query' ],
24 [ true, 'http://example.org', 'http://example.org#its-a-fragment' ],
25 // Different protocols
26 [ false, 'http://example.org', 'https://example.org' ],
27 [ false, 'https://example.org', 'http://example.org' ],
28 // Protocol relative servers always match http and https links
29 [ true, '//example.org', 'http://example.org' ],
30 [ true, '//example.org', 'https://example.org' ],
31 // But they don't match strange things like this
32 [ false, '//example.org', 'irc://example.org' ],
33 ];
34 }
35
36 /**
37 * Test to make sure ParserOutput::isLinkInternal behaves properly
38 * @dataProvider provideIsLinkInternal
39 * @covers ParserOutput::isLinkInternal
40 */
41 public function testIsLinkInternal( $shouldMatch, $server, $url ) {
42 $this->assertEquals( $shouldMatch, ParserOutput::isLinkInternal( $server, $url ) );
43 }
44
45 /**
46 * @covers ParserOutput::setExtensionData
47 * @covers ParserOutput::getExtensionData
48 */
49 public function testExtensionData() {
50 $po = new ParserOutput();
51
52 $po->setExtensionData( "one", "Foo" );
53
54 $this->assertEquals( "Foo", $po->getExtensionData( "one" ) );
55 $this->assertNull( $po->getExtensionData( "spam" ) );
56
57 $po->setExtensionData( "two", "Bar" );
58 $this->assertEquals( "Foo", $po->getExtensionData( "one" ) );
59 $this->assertEquals( "Bar", $po->getExtensionData( "two" ) );
60
61 $po->setExtensionData( "one", null );
62 $this->assertNull( $po->getExtensionData( "one" ) );
63 $this->assertEquals( "Bar", $po->getExtensionData( "two" ) );
64 }
65
66 /**
67 * @covers ParserOutput::setProperty
68 * @covers ParserOutput::getProperty
69 * @covers ParserOutput::unsetProperty
70 * @covers ParserOutput::getProperties
71 */
72 public function testProperties() {
73 $po = new ParserOutput();
74
75 $po->setProperty( 'foo', 'val' );
76
77 $properties = $po->getProperties();
78 $this->assertEquals( $po->getProperty( 'foo' ), 'val' );
79 $this->assertEquals( $properties['foo'], 'val' );
80
81 $po->setProperty( 'foo', 'second val' );
82
83 $properties = $po->getProperties();
84 $this->assertEquals( $po->getProperty( 'foo' ), 'second val' );
85 $this->assertEquals( $properties['foo'], 'second val' );
86
87 $po->unsetProperty( 'foo' );
88
89 $properties = $po->getProperties();
90 $this->assertEquals( $po->getProperty( 'foo' ), false );
91 $this->assertArrayNotHasKey( 'foo', $properties );
92 }
93
94 /**
95 * @covers ParserOutput::getText
96 * @dataProvider provideGetText
97 * @param array $options Options to getText()
98 * @param array $poState ParserOptions state fields to set
99 * @param string $text Parser text
100 * @param string $expect Expected output
101 */
102 public function testGetText( $options, $poState, $text, $expect ) {
103 $this->setMwGlobals( [
104 'wgArticlePath' => '/wiki/$1',
105 'wgScriptPath' => '/w',
106 'wgScript' => '/w/index.php',
107 ] );
108
109 $po = new ParserOutput( $text );
110
111 // Emulate Parser
112 $po->setEditSectionTokens( true );
113
114 if ( $poState ) {
115 $wrap = TestingAccessWrapper::newFromObject( $po );
116 foreach ( $poState as $key => $value ) {
117 $wrap->$key = $value;
118 }
119 }
120
121 $actual = $po->getText( $options );
122 $this->assertSame( $expect, $actual );
123 }
124
125 public static function provideGetText() {
126 // phpcs:disable Generic.Files.LineLength
127 $text = <<<EOF
128 <div class="mw-parser-output"><p>Test document.
129 </p>
130 <mw:toc><div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
131 <ul>
132 <li class="toclevel-1 tocsection-1"><a href="#Section_1"><span class="tocnumber">1</span> <span class="toctext">Section 1</span></a></li>
133 <li class="toclevel-1 tocsection-2"><a href="#Section_2"><span class="tocnumber">2</span> <span class="toctext">Section 2</span></a>
134 <ul>
135 <li class="toclevel-2 tocsection-3"><a href="#Section_2.1"><span class="tocnumber">2.1</span> <span class="toctext">Section 2.1</span></a></li>
136 </ul>
137 </li>
138 <li class="toclevel-1 tocsection-4"><a href="#Section_3"><span class="tocnumber">3</span> <span class="toctext">Section 3</span></a></li>
139 </ul>
140 </div>
141 </mw:toc>
142 <h2><span class="mw-headline" id="Section_1">Section 1</span><mw:editsection page="Test Page" section="1">Section 1</mw:editsection></h2>
143 <p>One
144 </p>
145 <h2><span class="mw-headline" id="Section_2">Section 2</span><mw:editsection page="Test Page" section="2">Section 2</mw:editsection></h2>
146 <p>Two
147 </p>
148 <h3><span class="mw-headline" id="Section_2.1">Section 2.1</span><mw:editsection page="Test Page" section="3">Section 2.1</mw:editsection></h3>
149 <p>Two point one
150 </p>
151 <h2><span class="mw-headline" id="Section_3">Section 3</span><mw:editsection page="Test Page" section="4">Section 3</mw:editsection></h2>
152 <p>Three
153 </p></div>
154 EOF;
155
156 return [
157 'No stateless options, default state' => [
158 [], [], $text, <<<EOF
159 <div class="mw-parser-output"><p>Test document.
160 </p>
161 <div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
162 <ul>
163 <li class="toclevel-1 tocsection-1"><a href="#Section_1"><span class="tocnumber">1</span> <span class="toctext">Section 1</span></a></li>
164 <li class="toclevel-1 tocsection-2"><a href="#Section_2"><span class="tocnumber">2</span> <span class="toctext">Section 2</span></a>
165 <ul>
166 <li class="toclevel-2 tocsection-3"><a href="#Section_2.1"><span class="tocnumber">2.1</span> <span class="toctext">Section 2.1</span></a></li>
167 </ul>
168 </li>
169 <li class="toclevel-1 tocsection-4"><a href="#Section_3"><span class="tocnumber">3</span> <span class="toctext">Section 3</span></a></li>
170 </ul>
171 </div>
172
173 <h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
174 <p>One
175 </p>
176 <h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=2" title="Edit section: Section 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
177 <p>Two
178 </p>
179 <h3><span class="mw-headline" id="Section_2.1">Section 2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=3" title="Edit section: Section 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
180 <p>Two point one
181 </p>
182 <h2><span class="mw-headline" id="Section_3">Section 3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=4" title="Edit section: Section 3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
183 <p>Three
184 </p></div>
185 EOF
186 ],
187 'No stateless options, TOC statefully disabled' => [
188 [], [ 'mTOCEnabled' => false ], $text, <<<EOF
189 <div class="mw-parser-output"><p>Test document.
190 </p>
191
192 <h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
193 <p>One
194 </p>
195 <h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=2" title="Edit section: Section 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
196 <p>Two
197 </p>
198 <h3><span class="mw-headline" id="Section_2.1">Section 2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=3" title="Edit section: Section 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
199 <p>Two point one
200 </p>
201 <h2><span class="mw-headline" id="Section_3">Section 3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=4" title="Edit section: Section 3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
202 <p>Three
203 </p></div>
204 EOF
205 ],
206 'No stateless options, section edits statefully disabled' => [
207 [], [ 'mEditSectionTokens' => false ], $text, <<<EOF
208 <div class="mw-parser-output"><p>Test document.
209 </p>
210 <div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
211 <ul>
212 <li class="toclevel-1 tocsection-1"><a href="#Section_1"><span class="tocnumber">1</span> <span class="toctext">Section 1</span></a></li>
213 <li class="toclevel-1 tocsection-2"><a href="#Section_2"><span class="tocnumber">2</span> <span class="toctext">Section 2</span></a>
214 <ul>
215 <li class="toclevel-2 tocsection-3"><a href="#Section_2.1"><span class="tocnumber">2.1</span> <span class="toctext">Section 2.1</span></a></li>
216 </ul>
217 </li>
218 <li class="toclevel-1 tocsection-4"><a href="#Section_3"><span class="tocnumber">3</span> <span class="toctext">Section 3</span></a></li>
219 </ul>
220 </div>
221
222 <h2><span class="mw-headline" id="Section_1">Section 1</span></h2>
223 <p>One
224 </p>
225 <h2><span class="mw-headline" id="Section_2">Section 2</span></h2>
226 <p>Two
227 </p>
228 <h3><span class="mw-headline" id="Section_2.1">Section 2.1</span></h3>
229 <p>Two point one
230 </p>
231 <h2><span class="mw-headline" id="Section_3">Section 3</span></h2>
232 <p>Three
233 </p></div>
234 EOF
235 ],
236 'Stateless options override stateful settings' => [
237 [ 'allowTOC' => true, 'enableSectionEditLinks' => true ],
238 [ 'mTOCEnabled' => false, 'mEditSectionTokens' => false ],
239 $text, <<<EOF
240 <div class="mw-parser-output"><p>Test document.
241 </p>
242 <div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
243 <ul>
244 <li class="toclevel-1 tocsection-1"><a href="#Section_1"><span class="tocnumber">1</span> <span class="toctext">Section 1</span></a></li>
245 <li class="toclevel-1 tocsection-2"><a href="#Section_2"><span class="tocnumber">2</span> <span class="toctext">Section 2</span></a>
246 <ul>
247 <li class="toclevel-2 tocsection-3"><a href="#Section_2.1"><span class="tocnumber">2.1</span> <span class="toctext">Section 2.1</span></a></li>
248 </ul>
249 </li>
250 <li class="toclevel-1 tocsection-4"><a href="#Section_3"><span class="tocnumber">3</span> <span class="toctext">Section 3</span></a></li>
251 </ul>
252 </div>
253
254 <h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
255 <p>One
256 </p>
257 <h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=2" title="Edit section: Section 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
258 <p>Two
259 </p>
260 <h3><span class="mw-headline" id="Section_2.1">Section 2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=3" title="Edit section: Section 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
261 <p>Two point one
262 </p>
263 <h2><span class="mw-headline" id="Section_3">Section 3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=4" title="Edit section: Section 3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
264 <p>Three
265 </p></div>
266 EOF
267 ],
268 'Statelessly disable section edit links' => [
269 [ 'enableSectionEditLinks' => false ], [], $text, <<<EOF
270 <div class="mw-parser-output"><p>Test document.
271 </p>
272 <div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
273 <ul>
274 <li class="toclevel-1 tocsection-1"><a href="#Section_1"><span class="tocnumber">1</span> <span class="toctext">Section 1</span></a></li>
275 <li class="toclevel-1 tocsection-2"><a href="#Section_2"><span class="tocnumber">2</span> <span class="toctext">Section 2</span></a>
276 <ul>
277 <li class="toclevel-2 tocsection-3"><a href="#Section_2.1"><span class="tocnumber">2.1</span> <span class="toctext">Section 2.1</span></a></li>
278 </ul>
279 </li>
280 <li class="toclevel-1 tocsection-4"><a href="#Section_3"><span class="tocnumber">3</span> <span class="toctext">Section 3</span></a></li>
281 </ul>
282 </div>
283
284 <h2><span class="mw-headline" id="Section_1">Section 1</span></h2>
285 <p>One
286 </p>
287 <h2><span class="mw-headline" id="Section_2">Section 2</span></h2>
288 <p>Two
289 </p>
290 <h3><span class="mw-headline" id="Section_2.1">Section 2.1</span></h3>
291 <p>Two point one
292 </p>
293 <h2><span class="mw-headline" id="Section_3">Section 3</span></h2>
294 <p>Three
295 </p></div>
296 EOF
297 ],
298 'Statelessly disable TOC' => [
299 [ 'allowTOC' => false ], [], $text, <<<EOF
300 <div class="mw-parser-output"><p>Test document.
301 </p>
302
303 <h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
304 <p>One
305 </p>
306 <h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=2" title="Edit section: Section 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
307 <p>Two
308 </p>
309 <h3><span class="mw-headline" id="Section_2.1">Section 2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=3" title="Edit section: Section 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
310 <p>Two point one
311 </p>
312 <h2><span class="mw-headline" id="Section_3">Section 3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=4" title="Edit section: Section 3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
313 <p>Three
314 </p></div>
315 EOF
316 ],
317 'Statelessly unwrap text' => [
318 [ 'unwrap' => true ], [], $text, <<<EOF
319 <p>Test document.
320 </p>
321 <div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
322 <ul>
323 <li class="toclevel-1 tocsection-1"><a href="#Section_1"><span class="tocnumber">1</span> <span class="toctext">Section 1</span></a></li>
324 <li class="toclevel-1 tocsection-2"><a href="#Section_2"><span class="tocnumber">2</span> <span class="toctext">Section 2</span></a>
325 <ul>
326 <li class="toclevel-2 tocsection-3"><a href="#Section_2.1"><span class="tocnumber">2.1</span> <span class="toctext">Section 2.1</span></a></li>
327 </ul>
328 </li>
329 <li class="toclevel-1 tocsection-4"><a href="#Section_3"><span class="tocnumber">3</span> <span class="toctext">Section 3</span></a></li>
330 </ul>
331 </div>
332
333 <h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
334 <p>One
335 </p>
336 <h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=2" title="Edit section: Section 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
337 <p>Two
338 </p>
339 <h3><span class="mw-headline" id="Section_2.1">Section 2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=3" title="Edit section: Section 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3>
340 <p>Two point one
341 </p>
342 <h2><span class="mw-headline" id="Section_3">Section 3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/w/index.php?title=Test_Page&amp;action=edit&amp;section=4" title="Edit section: Section 3">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
343 <p>Three
344 </p>
345 EOF
346 ],
347 'Unwrap without a mw-parser-output wrapper' => [
348 [ 'unwrap' => true ], [], '<div class="foobar">Content</div>', '<div class="foobar">Content</div>'
349 ],
350 ];
351 // phpcs:enable
352 }
353
354 }