' . '
ok
nope
' . "\n\n" . '
end
'; $expectedHtml = "\nhi" . '
ok
nope
' . "\n\n" . '
end
'; $expectedInnerHtml = "hi" . '
ok
nope
' . "\n\n" . '
end
'; $doc = new DOMDocument(); $doc->loadHTML( $html ); $ret = XMLSerializer::serialize( $doc ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'html', $ret ); $this->assertSame( $expectedHtml, $ret['html'] ); $ret = XMLSerializer::serialize( $doc, [ 'captureOffsets' => true ] ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'html', $ret ); $this->assertSame( $expectedHtml, $ret['html'] ); $ret = XMLSerializer::serialize( $doc, [ 'innerXML' => true ] ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'html', $ret ); $this->assertSame( $expectedInnerHtml, $ret['html'] ); } /** * @covers ::serialize */ public function testSerialize_captureOffsets() { $html = 'hi' . '
ok
nope
' . "\n\n" . '
end
'; $doc = new DOMDocument(); $doc->loadHTML( $html ); $ret = XMLSerializer::serialize( $doc, [ 'captureOffsets' => true ] ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'offsets', $ret ); $this->assertArrayHasKey( '123', $ret['offsets'] ); $this->assertSame( [ 0, 62 ], $ret['offsets']['123']['html'] ); $this->assertArrayNotHasKey( '234', $ret['offsets'] ); $this->assertArrayHasKey( '345', $ret['offsets'] ); $this->assertSame( [ 62, 85 ], $ret['offsets']['345']['html'] ); $ret = XMLSerializer::serialize( $doc, [ 'captureOffsets' => true, 'innerXML' => true ] ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'offsets', $ret ); $this->assertArrayHasKey( '123', $ret['offsets'] ); $this->assertSame( [ 0, 62 ], $ret['offsets']['123']['html'] ); $this->assertArrayNotHasKey( '234', $ret['offsets'] ); $this->assertArrayHasKey( '345', $ret['offsets'] ); $this->assertSame( [ 62, 85 ], $ret['offsets']['345']['html'] ); } /** * @covers ::serialize */ public function testSerialize_captureOffsets_template() { $html = 'hi' . '

a

' . '

b

' . '

c

' . ''; $doc = new DOMDocument(); $doc->loadHTML( $html ); $ret = XMLSerializer::serialize( $doc, [ 'captureOffsets' => true ] ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'offsets', $ret ); $this->assertArrayHasKey( 'mwAQ', $ret['offsets'] ); $this->assertArrayHasKey( 'mwAg', $ret['offsets'] ); $this->assertArrayNotHasKey( 'justhappenstobehere', $ret['offsets'] ); $this->assertSame( [ 0, 104 ], $ret['offsets']['mwAQ']['html'] ); $this->assertSame( [ 104, 122 ], $ret['offsets']['mwAg']['html'] ); } /** * @covers ::serialize */ public function testSerialize_captureOffsets_expandedAttrs() { $html = 'hi' // phpcs:ignore Generic.Files.LineLength.TooLong . '
color:red</span>"}]]}\'>boo
' . '

next!

' . ''; $doc = new DOMDocument(); $doc->loadHTML( $html ); $ret = XMLSerializer::serialize( $doc, [ 'captureOffsets' => true ] ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'offsets', $ret ); $this->assertArrayHasKey( 'mwAQ', $ret['offsets'] ); $this->assertArrayHasKey( 'mwAg', $ret['offsets'] ); $this->assertSame( [ 0, 680 ], $ret['offsets']['mwAQ']['html'] ); $this->assertSame( [ 680, 702 ], $ret['offsets']['mwAg']['html'] ); } /** * @covers ::serialize */ public function testSerialize_captureOffsets_extensionContentNestedInTemplates() { // Mostly scooped from, echo "{{Demografia/Apricale}}" | node tests/parse --prefix itwiki --dp $html = 'hi' // phpcs:ignore Generic.Files.LineLength.TooLong . '

Abitanti censiti

' // phpcs:ignore Generic.Files.LineLength.TooLong . '' . ''; $doc = new DOMDocument(); $doc->loadHTML( $html ); $ret = XMLSerializer::serialize( $doc, [ 'captureOffsets' => true ] ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'offsets', $ret ); $this->assertArrayHasKey( 'mwAQ', $ret['offsets'] ); $this->assertArrayNotHasKey( 'timeline', $ret['offsets'] ); $this->assertSame( [ 0, 372 ], $ret['offsets']['mwAQ']['html'] ); } /** * @covers ::serialize */ public function testSerialize_uppercaseTagnames() { $html = 'hi' . '
ok
nope
' . "\n\n" . '
end
'; $expectedHtml = "\nhi" . '
ok
nope
' . "\n\n" . '
end
'; $doc = new DOMDocument(); $doc->loadHTML( $html ); $ret = XMLSerializer::serialize( $doc ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'html', $ret ); $this->assertSame( $expectedHtml, $ret['html'] ); } /** * @covers ::serialize */ public function testSerialize_quotes() { $html = '' . '
' . '
' . '
' . '
' . ''; $expectedNonSmart = "\n" . '
' . '
' . '
' . '
' . ''; $expectedSmart = "\n" . '
' . '
' . '
' . '
' . ''; $doc = new DOMDocument(); $doc->loadHTML( $html ); $ret = XMLSerializer::serialize( $doc, [ 'smartQuote' => false ] ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'html', $ret ); $this->assertSame( $expectedNonSmart, $ret['html'] ); $ret = XMLSerializer::serialize( $doc, [ 'smartQuote' => true ] ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'html', $ret ); $this->assertSame( $expectedSmart, $ret['html'] ); } /** * @covers ::serialize */ public function testSerialize_emptyElements() { // Must have a single root node, otherwise libxml messes up parsing in NOIMPLIED mode. $html = '

'; $expectedHtml = '

'; $doc = new DOMDocument(); $doc->loadHTML( $html, LIBXML_HTML_NOIMPLIED ); $ret = XMLSerializer::serialize( $doc, [ 'smartQuote' => false ] ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'html', $ret ); $this->assertSame( $expectedHtml, $ret['html'] ); } /** * @covers ::serialize */ public function testSerialize_rawContent() { $html = ''; $doc = new DOMDocument(); $doc->loadHTML( $html, LIBXML_HTML_NOIMPLIED ); $ret = XMLSerializer::serialize( $doc, [ 'smartQuote' => false ] ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'html', $ret ); $this->assertSame( $html, $ret['html'] ); } /** * @covers ::serialize */ public function testSerialize_newlineStrippingElements() { // Must have a single root node, otherwise libxml messes up parsing in NOIMPLIED mode. // This test looks confusing because DOMDocument::loadHTML doesn't fully follow the spec; // it should strip the first newline within a pre block. $html = "
\n
\n
"; $expectedHtml = "
\n\n
\n
"; $doc = new DOMDocument(); $doc->loadHTML( $html, LIBXML_HTML_NOIMPLIED ); $ret = XMLSerializer::serialize( $doc, [ 'smartQuote' => false ] ); $this->assertIsArray( $ret ); $this->assertArrayHasKey( 'html', $ret ); $this->assertSame( $expectedHtml, $ret['html'] ); } /** * @covers ::encodeHtmlEntities * @dataProvider provideEncodeHtmlEntities */ public function testEncodeHtmlEntities( $raw, $encodeChars, $expected ) { $XMLSerializer = TestingAccessWrapper::newFromClass( XMLSerializer::class ); $actual = $XMLSerializer->encodeHtmlEntities( $raw, $encodeChars ); $this->assertEquals( $expected, $actual ); } public function provideEncodeHtmlEntities() { return [ [ 'ab&cd<>e"f\'g&h"j', '&<\'"', 'ab&cd<>e"f'g&h"j' ], [ 'ab&cd<>e"f\'g&h"j', '&<"', 'ab&cd<>e"f\'g&h"j' ], [ 'ab&cd<>e"f\'g&h"j', '&<', 'ab&cd<>e"f\'g&h"j' ], ]; } }