X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;f=vendor%2Fmasterminds%2Fhtml5%2Ftest%2FHTML5%2FSerializer%2FOutputRulesTest.php;fp=vendor%2Fmasterminds%2Fhtml5%2Ftest%2FHTML5%2FSerializer%2FOutputRulesTest.php;h=72253d3482969c0914489301880e09a5b518fff6;hb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;hp=0000000000000000000000000000000000000000;hpb=aea91e65e895364e460983b890e295aa5d5540a5;p=yaffs-website diff --git a/vendor/masterminds/html5/test/HTML5/Serializer/OutputRulesTest.php b/vendor/masterminds/html5/test/HTML5/Serializer/OutputRulesTest.php new file mode 100644 index 000000000..72253d348 --- /dev/null +++ b/vendor/masterminds/html5/test/HTML5/Serializer/OutputRulesTest.php @@ -0,0 +1,650 @@ + + + + + Test + + +

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)); + } + + 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: ')!==false); + } +}