Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F5946143
RemexDriverTest.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
RemexDriverTest.php
View Options
<?php
use
MediaWiki\Config\HashConfig
;
use
MediaWiki\Config\ServiceOptions
;
use
MediaWiki\MainConfigNames
;
use
MediaWiki\Parser\Sanitizer
;
class
RemexDriverTest
extends
MediaWikiUnitTestCase
{
private
const
REMEX_TIDY_TEST_DATA
=
[
[
'Empty string'
,
""
,
""
],
[
'Simple p-wrap'
,
"x"
,
"<p>x</p>"
],
[
'No p-wrap of blank node'
,
" "
,
" "
],
[
'p-wrap terminated by div'
,
"x<div></div>"
,
"<p>x</p><div></div>"
],
[
'p-wrap not terminated by span'
,
"x<span></span>"
,
"<p>x<span></span></p>"
],
[
'An element is non-blank and so gets p-wrapped'
,
"<span></span>"
,
"<p><span></span></p>"
],
[
'The blank flag is set after a block-level element'
,
"<div></div> "
,
"<div></div> "
],
[
'Blank detection between two block-level elements'
,
"<div></div> <div></div>"
,
"<div></div> <div></div>"
],
[
'But p-wrapping of non-blank content works after an element'
,
"<div></div>x"
,
"<div></div><p>x</p>"
],
[
'p-wrapping between two block-level elements'
,
"<div></div>x<div></div>"
,
"<div></div><p>x</p><div></div>"
],
[
'p-wrap inside blockquote'
,
"<blockquote>x</blockquote>"
,
"<blockquote><p>x</p></blockquote>"
],
[
'A comment is blank for p-wrapping purposes'
,
"<!-- x -->"
,
"<!-- x -->"
],
[
'A comment is blank even when a p-wrap was opened by a text node'
,
" <!-- x -->"
,
" <!-- x -->"
],
[
'A comment does not open a p-wrap'
,
"<!-- x -->x"
,
"<!-- x --><p>x</p>"
],
[
'A comment does not close a p-wrap'
,
"x<!-- x -->"
,
"<p>x<!-- x --></p>"
],
[
'Empty li'
,
"<ul><li></li></ul>"
,
"<ul><li class=
\"
mw-empty-elt
\"
></li></ul>"
],
[
'li with element'
,
"<ul><li><span></span></li></ul>"
,
"<ul><li><span></span></li></ul>"
],
[
'li with text'
,
"<ul><li>x</li></ul>"
,
"<ul><li>x</li></ul>"
],
[
'Empty tr'
,
"<table><tbody><tr></tr></tbody></table>"
,
"<table><tbody><tr class=
\"
mw-empty-elt
\"
></tr></tbody></table>"
],
[
'Empty p'
,
"<p>
\n
</p>"
,
"<p class=
\"
mw-empty-elt
\"
>
\n
</p>"
],
[
'No p-wrapping of an inline element which contains a block element (T150317)'
,
"<small><div>x</div></small>"
,
"<small><div>x</div></small>"
],
[
'p-wrapping of an inline element which contains an inline element'
,
"<small><b>x</b></small>"
,
"<p><small><b>x</b></small></p>"
],
[
'p-wrapping is enabled in a blockquote in an inline element'
,
"<small><blockquote>x</blockquote></small>"
,
"<small><blockquote><p>x</p></blockquote></small>"
],
[
'All bare text should be p-wrapped even when surrounded by block tags'
,
"<small><blockquote>x</blockquote></small>y<div></div>z"
,
"<small><blockquote><p>x</p></blockquote></small><p>y</p><div></div><p>z</p>"
],
[
'Split tag stack 1'
,
"<small>x<div>y</div>z</small>"
,
"<p><small>x</small></p><small><div>y</div></small><p><small>z</small></p>"
],
[
'Split tag stack 2'
,
"<small><div>y</div>z</small>"
,
"<small><div>y</div></small><p><small>z</small></p>"
],
[
'Split tag stack 3'
,
"<small>x<div>y</div></small>"
,
"<p><small>x</small></p><small><div>y</div></small>"
],
[
'Split tag stack 4 (modified to use splittable tag)'
,
"a<code>b<i>c<div>d</div></i>e</code>"
,
"<p>a<code>b<i>c</i></code></p><code><i><div>d</div></i></code><p><code>e</code></p>"
],
[
"Split tag stack regression check 1"
,
"x<span><div>y</div></span>"
,
"<p>x</p><span><div>y</div></span>"
],
[
"Split tag stack regression check 2 (modified to use splittable tag)"
,
"a<code><i><div>d</div></i>e</code>"
,
"<p>a</p><code><i><div>d</div></i></code><p><code>e</code></p>"
],
// Simple tests from pwrap.js
[
'Simple pwrap test 1'
,
'a'
,
'<p>a</p>'
],
[
'<span> is not a splittable tag'
,
'<span>x<div>a</div>y</span> <span>x<div></div>y</span>'
,
'<span>x<div>a</div>y</span> <span>x<div></div>y</span>'
,
],
[
'<span> is not a splittable tag, but gets p-wrapped in simple wrapping scenarios'
,
'<span>a</span>'
,
'<p><span>a</span></p>'
],
[
'Simple pwrap test 3'
,
'x <div>a</div> <div>b</div> y'
,
'<p>x </p><div>a</div> <div>b</div><p> y</p>'
],
[
'Simple pwrap test 4'
,
'x<!--c--> <div>a</div> <div>b</div> <!--c-->y'
,
'<p>x<!--c--> </p><div>a</div> <div>b</div> <!--c--><p>y</p>'
],
// Complex tests from pwrap.js
[
'Complex pwrap test 1'
,
'<i>x<div>a</div>y</i>'
,
'<p><i>x</i></p><i><div>a</div></i><p><i>y</i></p>'
],
[
'Complex pwrap test 2'
,
'a<small>b</small><i>c<div>d</div>e</i>f'
,
'<p>a<small>b</small><i>c</i></p><i><div>d</div></i><p><i>e</i>f</p>'
],
[
'Complex pwrap test 3'
,
'a<small>b<i>c<div>d</div></i>e</small>'
,
'<p>a<small>b<i>c</i></small></p><small><i><div>d</div></i></small><p><small>e</small></p>'
],
[
'Complex pwrap test 4'
,
'x<small><div>y</div></small>'
,
'<p>x</p><small><div>y</div></small>'
],
[
'Complex pwrap test 5'
,
'a<small><i><div>d</div></i>e</small>'
,
'<p>a</p><small><i><div>d</div></i></small><p><small>e</small></p>'
],
[
'Complex pwrap test 6'
,
'<i>a<div>b</div>c<b>d<div>e</div>f</b>g</i>'
,
'<p><i>a</i></p><i><div>b</div></i><p><i>c<b>d</b></i></p><i><b><div>e</div></b></i><p><i><b>f</b>g</i></p>'
],
/* FIXME the second <b> causes a stack split which clones the <i> even
* though no <p> is actually generated
[
'Complex pwrap test 7',
'<i><b><font><div>x</div></font></b><div>y</div><b><font><div>z</div></font></b></i>',
'<i><b><font><div>x</div></font></b><div>y</div><b><font><div>z</div></font></b></i>'
],
*/
// New local tests
[
'Blank text node after block end'
,
'<small>x<div>y</div> <b>z</b></small>'
,
'<p><small>x</small></p><small><div>y</div></small><p><small> <b>z</b></small></p>'
],
[
'Text node fostering (FIXME: wrap missing)'
,
'<table>x</table>'
,
'x<table></table>'
],
[
'Blockquote fostering'
,
'<table><blockquote>x</blockquote></table>'
,
'<blockquote><p>x</p></blockquote><table></table>'
],
[
'Block element fostering'
,
'<table><div>x'
,
'<div>x</div><table></table>'
],
[
'Formatting element fostering (FIXME: wrap missing)'
,
'<table><b>x'
,
'<b>x</b><table></table>'
],
[
'AAA clone of p-wrapped element (FIXME: empty b)'
,
'<b>x<p>y</b>z</p>'
,
'<p><b>x</b></p><b></b><p><b>y</b>z</p>'
,
],
[
'AAA with fostering (FIXME: wrap missing)'
,
'<table><b>1<p>2</b>3</p>'
,
'<b>1</b><p><b>2</b>3</p><table></table>'
],
[
'AAA causes reparent of p-wrapped text node (T178632)'
,
'<i><blockquote>x</i></blockquote>'
,
'<i></i><blockquote><p><i>x</i></p></blockquote>'
,
],
[
'p-wrap ended by reparenting (T200827)'
,
'<i><blockquote><p></i>'
,
'<i></i><blockquote><p><i></i></p><p><i></i></p></blockquote>'
,
],
[
'style tag isn
\'
t p-wrapped (T186965)'
,
'<style>/* ... */</style>'
,
'<style>/* ... */</style>'
,
],
[
'link tag isn
\'
t p-wrapped (T186965)'
,
'<link rel="foo" href="bar" />'
,
'<link rel="foo" href="bar" />'
,
],
[
'style tag doesn
\'
t split p-wrapping (T208901)'
,
'foo <style>/* ... */</style> bar'
,
'<p>foo <style>/* ... */</style> bar</p>'
,
],
[
'link tag doesn
\'
t split p-wrapping (T208901)'
,
'foo <link rel="foo" href="bar" /> bar'
,
'<p>foo <link rel="foo" href="bar" /> bar</p>'
,
],
// From the old TidyTest class
[
'<mw:editsection> should survive tidy'
,
'<mw:editsection page="foo" section="bar">foo</mw:editsection>'
,
'<mw:editsection page="foo" section="bar">foo</mw:editsection>'
,
],
[
'TOC_PLACEHOLDER should survive tidy'
,
'<meta property="mw:PageProp/toc" />'
,
'<meta property="mw:PageProp/toc" />'
,
],
[
'<link> should survive tidy'
,
'<link foo="bar"/>foo'
,
"<link foo=
\"
bar
\"
/><p>foo</p>"
,
],
[
'<meta> should survive tidy'
,
'<meta foo="bar"/>foo'
,
"<meta foo=
\"
bar
\"
/><p>foo</p>"
,
],
[
'Unicode combining characters (T387130)'
,
"<p>
\u
{0338} <!--comment-->
\u
{0338}</p>"
,
'<p≯ <!--comment--≯</p>'
,
],
];
public
static
function
provider
()
{
$testMathML
=
<<<'MathML'
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mrow>
<mi>a</mi>
<mo>⁢</mo>
<msup>
<mi>x</mi>
<mn>2</mn>
</msup>
<mo>+</mo>
<mi>b</mi>
<mo>⁢ </mo>
<mi>x</mi>
<mo>+</mo>
<mi>c</mi>
</mrow>
</math>
MathML;
$testMathML
=
Sanitizer
::
normalizeCharReferences
(
$testMathML
);
return
array_merge
(
self
::
REMEX_TIDY_TEST_DATA
,
[
[
'<math> should survive tidy'
,
$testMathML
,
$testMathML
,
]
]
);
}
/**
* @dataProvider provider
* @covers \MediaWiki\Tidy\RemexCompatFormatter
* @covers \MediaWiki\Tidy\RemexCompatMunger
* @covers \MediaWiki\Tidy\RemexDriver
* @covers \MediaWiki\Tidy\RemexMungerData
*/
public
function
testTidy
(
$desc
,
$input
,
$expected
)
{
$r
=
new
MediaWiki\Tidy\RemexDriver
(
new
ServiceOptions
(
MediaWiki\Tidy\RemexDriver
::
CONSTRUCTOR_OPTIONS
,
new
HashConfig
(
[
MainConfigNames
::
TidyConfig
=>
[],
MainConfigNames
::
ParserEnableLegacyMediaDOM
=>
false
,
]
)
)
);
$result
=
$r
->
tidy
(
$input
);
$this
->
assertEquals
(
$expected
,
$result
,
$desc
);
}
public
static
function
html5libProvider
()
{
$files
=
json_decode
(
file_get_contents
(
__DIR__
.
'/html5lib-tests.json'
),
true
);
$tests
=
[];
foreach
(
$files
as
$file
=>
$fileTests
)
{
foreach
(
$fileTests
as
$i
=>
$test
)
{
$tests
[]
=
[
"$file:$i"
,
$test
[
'data'
]
];
}
}
return
$tests
;
}
/**
* This is a quick and dirty test to make sure none of the html5lib tests
* generate exceptions. We don't really know what the expected output is.
*
* @dataProvider html5libProvider
* @coversNothing
*/
public
function
testHtml5Lib
(
$desc
,
$input
)
{
$r
=
new
MediaWiki\Tidy\RemexDriver
(
new
ServiceOptions
(
MediaWiki\Tidy\RemexDriver
::
CONSTRUCTOR_OPTIONS
,
new
HashConfig
(
[
MainConfigNames
::
TidyConfig
=>
[],
MainConfigNames
::
ParserEnableLegacyMediaDOM
=>
false
,
]
)
)
);
$result
=
$r
->
tidy
(
$input
);
$this
->
assertTrue
(
true
,
$desc
);
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Oct 2 2026, 19:25 (6 w, 1 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
37/7b/b02d57c3a037379c72c746ebcf3d
Default Alt Text
RemexDriverTest.php (10 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment