6 class HtmlFormatterTest
extends MediaWikiTestCase
{
9 * Use TidySupport to check whether we should use $wgTidyInternal.
11 * The Tidy extension in HHVM does not support error text return, so it is
12 * nominally usable, but does not pass tests which require error text from
15 protected function setUp() {
17 $tidySupport = new TidySupport();
18 $this->setMwGlobals( 'wgTidyInternal', $tidySupport->isInternal() );
22 * @dataProvider getHtmlData
24 * @param string $input
25 * @param string $expectedText
26 * @param array $expectedRemoved
27 * @param callable|bool $callback
29 public function testTransform( $input, $expectedText,
30 $expectedRemoved = array(), $callback = false
32 $input = self
::normalize( $input );
33 $formatter = new HtmlFormatter( HtmlFormatter
::wrapHTML( $input ) );
35 $callback( $formatter );
37 $removedElements = $formatter->filterContent();
38 $html = $formatter->getText();
40 foreach ( $removedElements as $removedElement ) {
41 $removed[] = self
::normalize( $formatter->getText( $removedElement ) );
43 $expectedRemoved = array_map( 'self::normalize', $expectedRemoved );
45 $this->assertValidHtmlSnippet( $html );
46 $this->assertEquals( self
::normalize( $expectedText ), self
::normalize( $html ) );
47 $this->assertEquals( asort( $expectedRemoved ), asort( $removed ) );
50 private static function normalize( $s ) {
51 return str_replace( "\n", '',
52 str_replace( "\r", '', $s ) // "yay" to Windows!
56 public function getHtmlData() {
57 $removeImages = function ( HtmlFormatter
$f ) {
60 $removeTags = function ( HtmlFormatter
$f ) {
61 $f->remove( array( 'table', '.foo', '#bar', 'div.baz' ) );
63 $flattenSomeStuff = function ( HtmlFormatter
$f ) {
64 $f->flatten( array( 's', 'div' ) );
66 $flattenEverything = function ( HtmlFormatter
$f ) {
70 // remove images if asked
72 '<img src="/foo/bar.jpg" alt="Blah"/>',
74 array( '<img src="/foo/bar.jpg" alt="Blah">' ),
79 // @codingStandardsIgnoreStart Ignore long line warnings.
80 '<table><tr><td>foo</td></tr></table><div class="foo">foo</div><div class="foo quux">foo</div><span id="bar">bar</span>
81 <strong class="foo" id="bar">foobar</strong><div class="notfoo">test</div><div class="baz"/>
82 <span class="baz">baz</span>',
83 // @codingStandardsIgnoreEnd
84 '<div class="notfoo">test</div>
85 <span class="baz">baz</span>',
87 '<table><tr><td>foo</td></tr></table>',
88 '<div class="foo">foo</div>',
89 '<div class="foo quux">foo</div>',
90 '<span id="bar">bar</span>',
91 '<strong class="foo" id="bar">foobar</strong>',
96 // don't flatten tags that start like chosen ones
98 '<div><s>foo</s> <span>bar</span></div>',
99 'foo <span>bar</span>',
105 '<div style="foo">bar<sup>2</sup></div>',
110 // UTF-8 preservation and security
112 '<span title="" \' &"><Тест!></span> &<&&&&',
113 '<span title="" \' &"><Тест!></span> &<&&&&',
115 $removeTags, // Have some rules to trigger a DOM parse
117 // https://phabricator.wikimedia.org/T55086
119 'Foo<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup>'
120 . ' <a href="/wiki/Bar" title="Bar" class="mw-redirect">Bar</a>',
121 'Foo<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup>'
122 . ' <a href="/wiki/Bar" title="Bar" class="mw-redirect">Bar</a>',
127 public function testQuickProcessing() {
128 $f = new MockHtmlFormatter( 'foo' );
130 $this->assertFalse( $f->hasDoc
, 'HtmlFormatter should not needlessly parse HTML' );
134 class MockHtmlFormatter
extends HtmlFormatter
{
135 public $hasDoc = false;
137 public function getDoc() {
138 $this->hasDoc
= true;
139 return parent
::getDoc();