This is a test.

'; /** * @var HTML5 */ protected $html5; public function setUp() { $this->html5 = $this->getInstance(); } /** * Using reflection we make a protected method accessible for testing. * * @param string $name * The name of the method on the Traverser class to test * * @return \ReflectionMethod for the specified method */ public function getProtectedMethod($name) { $class = new \ReflectionClass('\Masterminds\HTML5\Serializer\OutputRules'); $method = $class->getMethod($name); $method->setAccessible(true); return $method; } public function getTraverserProtectedProperty($name) { $class = new \ReflectionClass('\Masterminds\HTML5\Serializer\Traverser'); $property = $class->getProperty($name); $property->setAccessible(true); return $property; } public function getOutputRules($options = array()) { $options = $options + $this->html5->getOptions(); $stream = fopen('php://temp', 'w'); $dom = $this->html5->loadHTML($this->markup); $r = new OutputRules($stream, $options); $t = new Traverser($dom, $stream, $r, $options); return array( $r, $stream, ); } public function testDocument() { $dom = $this->html5->loadHTML('foo'); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $r->document($dom); $expected = '' . PHP_EOL . 'foo' . PHP_EOL; $this->assertEquals($expected, stream_get_contents($stream, -1, 0)); } public function testEmptyDocument() { $dom = $this->html5->loadHTML(''); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $r->document($dom); $expected = '' . PHP_EOL; $this->assertEquals($expected, stream_get_contents($stream, -1, 0)); } public function testDoctype() { $dom = $this->html5->loadHTML('foo'); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $m = $this->getProtectedMethod('doctype'); $m->invoke($r, 'foo'); $this->assertEquals('' . PHP_EOL, stream_get_contents($stream, -1, 0)); } public function testElement() { $dom = $this->html5->loadHTML( '
foo bar baz
'); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $list = $dom->getElementsByTagName('div'); $r->element($list->item(0)); $this->assertEquals('
foo bar baz
', stream_get_contents($stream, -1, 0)); } public function testSerializeWithNamespaces() { $this->html5 = $this->getInstance(array( 'xmlNamespaces' => true, )); $source = ' xy svg
y '; $dom = $this->html5->loadHTML($source, array( 'xmlNamespaces' => true, )); $this->assertFalse($this->html5->hasErrors(), print_r($this->html5->getErrors(), 1)); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $t->walk(); $rendered = stream_get_contents($stream, -1, 0); $clear = function ($s) { return trim(preg_replace('/[\s]+/', ' ', $s)); }; $this->assertEquals($clear($source), $clear($rendered)); } public function testElementWithScript() { $dom = $this->html5->loadHTML( '
foo bar baz
'); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $script = $dom->getElementsByTagName('script'); $r->element($script->item(0)); $this->assertEquals( '', stream_get_contents($stream, -1, 0)); } public function testElementWithStyle() { $dom = $this->html5->loadHTML( '
foo bar baz
'); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $style = $dom->getElementsByTagName('style'); $r->element($style->item(0)); $this->assertEquals('', stream_get_contents($stream, -1, 0)); } public function testOpenTag() { $dom = $this->html5->loadHTML('
foo bar baz
'); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $list = $dom->getElementsByTagName('div'); $m = $this->getProtectedMethod('openTag'); $m->invoke($r, $list->item(0)); $this->assertEquals('
', stream_get_contents($stream, -1, 0)); } public function testCData() { $dom = $this->html5->loadHTML('
'); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $list = $dom->getElementsByTagName('div'); $r->cdata($list->item(0)->childNodes->item(0)); $this->assertEquals('', stream_get_contents($stream, -1, 0)); $dom = $this->html5->loadHTML('
'); $dom->getElementById('foo')->appendChild(new \DOMCdataSection(']]>Foo<[![CDATA test ]]>')); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $list = $dom->getElementsByTagName('div'); $r->cdata($list->item(0)->childNodes->item(0)); $this->assertEquals('Foo<[![CDATA test ]]]]>]]>', stream_get_contents($stream, -1, 0)); } public function testComment() { $dom = $this->html5->loadHTML('
'); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $list = $dom->getElementsByTagName('div'); $r->comment($list->item(0)->childNodes->item(0)); $this->assertEquals('', stream_get_contents($stream, -1, 0)); $dom = $this->html5->loadHTML('
'); $dom->getElementById('foo')->appendChild(new \DOMComment(' --> Foo -->')); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $list = $dom->getElementsByTagName('div'); $r->comment($list->item(0)->childNodes->item(0)); // Could not find more definitive guidelines on what this should be. Went with // what the HTML5 spec says and what \DOMDocument::saveXML() produces. $this->assertEquals(' --> Foo -->-->', stream_get_contents($stream, -1, 0)); } public function testText() { $dom = $this->html5->loadHTML(' '); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $list = $dom->getElementsByTagName('script'); $r->text($list->item(0)->childNodes->item(0)); $this->assertEquals('baz();', stream_get_contents($stream, -1, 0)); $dom = $this->html5->loadHTML(' '); $foo = $dom->getElementById('foo'); $foo->appendChild(new \DOMText('')); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $r->text($foo->firstChild); $this->assertEquals('<script>alert("hi");</script>', stream_get_contents($stream, -1, 0)); } public function testNl() { list($o, $s) = $this->getOutputRules(); $m = $this->getProtectedMethod('nl'); $m->invoke($o); $this->assertEquals(PHP_EOL, stream_get_contents($s, -1, 0)); } public function testWr() { list($o, $s) = $this->getOutputRules(); $m = $this->getProtectedMethod('wr'); $m->invoke($o, 'foo'); $this->assertEquals('foo', stream_get_contents($s, -1, 0)); } public function getEncData() { return array( array( false, '&\'<>"', '&\'<>"', '&'<>"', ), array( false, 'This + is. a < test', 'This + is. a < test', 'This + is. a < test', ), array( false, '.+#', '.+#', '.+#', ), array( true, '.+#\'', '.+#\'', '.+#'', ), array( true, '&".<', '&".<', '&".<', ), array( true, '&\'<>"', '&\'<>"', '&'<>"', ), array( true, "\xc2\xa0\"'", ' "\'', ' "'', ), ); } /** * Test basic encoding of text. * * @dataProvider getEncData */ public function testEnc($isAttribute, $test, $expected, $expectedEncoded) { list($o, $s) = $this->getOutputRules(); $m = $this->getProtectedMethod('enc'); $this->assertEquals($expected, $m->invoke($o, $test, $isAttribute)); list($o, $s) = $this->getOutputRules(array( 'encode_entities' => true, )); $m = $this->getProtectedMethod('enc'); $this->assertEquals($expectedEncoded, $m->invoke($o, $test, $isAttribute)); } /** * Test basic encoding of text. * * @dataProvider getEncData */ public function testEscape($isAttribute, $test, $expected, $expectedEncoded) { list($o, $s) = $this->getOutputRules(); $m = $this->getProtectedMethod('escape'); $this->assertEquals($expected, $m->invoke($o, $test, $isAttribute)); } public function booleanAttributes() { return array( array(''), array(''), array(''), array(''), array(''), array(''), array('
'), array(''), array('
'), array(''), ); } /** * @dataProvider booleanAttributes */ public function testBooleanAttrs($html) { $dom = $this->html5->loadHTML('' . $html . ''); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $node = $dom->getElementsByTagName('body')->item(0)->firstChild; $m = $this->getProtectedMethod('attrs'); $m->invoke($r, $node); $content = stream_get_contents($stream, -1, 0); $html = preg_replace('~<[a-z]+(.*)>~', '\1', $html); $html = preg_replace('~<[a-z]+(.*)/?>~', '\1', $html); $this->assertEquals($content, $html); } public function testAttrs() { $dom = $this->html5->loadHTML('
foo bar baz
'); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $list = $dom->getElementsByTagName('div'); $m = $this->getProtectedMethod('attrs'); $m->invoke($r, $list->item(0)); $content = stream_get_contents($stream, -1, 0); $this->assertEquals(' id="foo" class="bar baz"', $content); } public function testSvg() { $dom = $this->html5->loadHTML( '
foo bar baz
'); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $list = $dom->getElementsByTagName('svg'); $r->element($list->item(0)); $contents = stream_get_contents($stream, -1, 0); $this->assertRegExp('||', $contents); $this->assertRegExp('||', $contents); $this->assertRegExp('||', $contents); } public function testMath() { $dom = $this->html5->loadHTML( '
foo bar baz
x ± y '); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $list = $dom->getElementsByTagName('math'); $r->element($list->item(0)); $content = stream_get_contents($stream, -1, 0); $this->assertRegExp('||', $content); $this->assertRegExp('||', $content); } public function testProcessorInstruction() { $dom = $this->html5->loadHTMLFragment(''); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $r->processorInstruction($dom->firstChild); $content = stream_get_contents($stream, -1, 0); $this->assertRegExp('|<\?foo bar \?>|', $content); } public function testAddressTag() { $dom = $this->html5->loadHTML( '
Dave Raggett, Arnaud Le Hors, contact persons for the W3C HTML Activity
'); $stream = fopen('php://temp', 'w'); $r = new OutputRules($stream, $this->html5->getOptions()); $t = new Traverser($dom, $stream, $r, $this->html5->getOptions()); $list = $dom->getElementsByTagName('address'); $r->element($list->item(0)); $contents = stream_get_contents($stream, -1, 0); $this->assertRegExp('|
|', $contents); $this->assertRegExp('|Dave Raggett,|', $contents); $this->assertRegExp('|Arnaud Le Hors,|', $contents); $this->assertRegExp('|contact persons for the W3C HTML Activity|', $contents); $this->assertRegExp('|
|', $contents); } /** * Ensure direct DOM manipulation doesn't break TEXT_RAW elements (iframe, script, etc...). */ public function testHandlingInvalidRawContent() { $dom = $this->html5->loadHTML( ' '); $badNode = $dom->createElement('p', 'Bar'); // modify the content of the TEXT_RAW element: ')); } }