diff options
Diffstat (limited to 'test/SimpleTest/HTML5')
-rw-r--r-- | test/SimpleTest/HTML5/DataHarness.php | 48 | ||||
-rw-r--r-- | test/SimpleTest/HTML5/JSONHarness.php | 21 | ||||
-rw-r--r-- | test/SimpleTest/HTML5/TestData.php | 167 | ||||
-rw-r--r-- | test/SimpleTest/HTML5/TestDataHarness.php | 18 | ||||
-rw-r--r-- | test/SimpleTest/HTML5/TestDataTest.php | 31 | ||||
-rw-r--r-- | test/SimpleTest/HTML5/TestDataTest/sample.dat | 7 |
6 files changed, 292 insertions, 0 deletions
diff --git a/test/SimpleTest/HTML5/DataHarness.php b/test/SimpleTest/HTML5/DataHarness.php new file mode 100644 index 0000000..844b1fc --- /dev/null +++ b/test/SimpleTest/HTML5/DataHarness.php @@ -0,0 +1,48 @@ +<?php + +/** + * Modified test-case supertype for running tests that are not + * test method based, but based off of test data that resides in + * files. + */ +SimpleTest::ignore('HTML5_DataHarness'); +abstract class HTML5_DataHarness extends UnitTestCase +{ + /** + * Filled in by HTML5_TestData::generateTestCases() + */ + protected $filename; + private $tests; + /** + * Invoked by the runner, it is the function responsible for executing + * the test and delivering results. + * @param $test Some easily usable representation of the test + */ + abstract public function invoke($test); + /** + * Returns a list of tests that can be executed. The list members will + * be passed to invoke(). Return an iterator if you don't want to load + * all test into memory + */ + abstract public function getDataTests(); + /** + * Returns a description of the test + */ + abstract public function getDescription($test); + public function getTests() { + $this->tests = $this->getDataTests(); + // 1-indexed, to be consistent with Python + $ret = array(); + for ($i = 1; $i <= count($this->tests); $i++) { + $ret[] = "test_$i"; + } + return $ret; + } + /** + * Emulates our test functions + */ + public function __call($name, $args) { + list($test, $i) = explode("_", $name); + $this->invoke($this->tests[$i-1]); + } +} diff --git a/test/SimpleTest/HTML5/JSONHarness.php b/test/SimpleTest/HTML5/JSONHarness.php new file mode 100644 index 0000000..dd1cf66 --- /dev/null +++ b/test/SimpleTest/HTML5/JSONHarness.php @@ -0,0 +1,21 @@ +<?php + +/** + * Implementation specifically for JSON format files. + */ +SimpleTest::ignore('HTML5_JSONHarness'); +abstract class HTML5_JSONHarness extends HTML5_DataHarness +{ + protected $data; + public function __construct() { + parent::__construct(); + $this->data = json_decode(file_get_contents($this->filename)); + } + public function getDescription($test) { + return $test->description; + } + public function getDataTests() { + return isset($this->data->tests) ? $this->data->tests : array(); + // could be a weird xmlViolationsTest + } +} diff --git a/test/SimpleTest/HTML5/TestData.php b/test/SimpleTest/HTML5/TestData.php new file mode 100644 index 0000000..39e9e44 --- /dev/null +++ b/test/SimpleTest/HTML5/TestData.php @@ -0,0 +1,167 @@ +<?php + +/** + * Interface for retreiving test files. Also represents a .dat file. + */ +class HTML5_TestData +{ + /** + * Retrieves a list of test filenames from a directory. + */ + static public function getList($type, $glob) { + $full_glob = + realpath(dirname(__FILE__) . '/../../../testdata/' . $type) . + DIRECTORY_SEPARATOR . $glob; + return glob($full_glob); + } + /** + * This function generates unique test case classes corresponding + * to test files in the testdata directory. + */ + static public function generateTestCases($base, $prefix, $type, $glob) { + foreach (HTML5_TestData::getList($type, $glob) as $filename) { + $name = str_replace('-', '', basename($filename)); + $name = ucfirst(substr($name, 0, strcspn($name, '.'))); + if ($type === 'tree-construction') { + // skip XFOREIGN tests for now + $num = (int) substr($name, 5); + if ($num >= 9) continue; + } + $pfilename = var_export($filename, true); + $code = "class $prefix$name extends $base { public \$filename = $pfilename; }"; + eval($code); + } + } + + public $tests; + + public function __construct($filename) { + $test = array(); + $newTestHeading = null; + $heading = null; + foreach (explode("\n", file_get_contents($filename)) as $line) { + if ($line !== '' && $line[0] === '#') { + $newHeading = substr($line, 1); + if (!$newTestHeading) { + $newTestHeading = $newHeading; + } elseif ($newHeading === $newTestHeading) { + $test[$heading] = substr($test[$heading], 0, -1); + $this->tests[] = $test; + $test = array(); + } + $heading = $newHeading; + $test[$heading] = ''; + } elseif ($heading) { + $test[$heading] .= "$line\n"; + } + } + if (!empty($test)) { + $test[$heading] = substr($test[$heading], 0, -1); + $this->tests[] = $test; + } + // normalize + foreach ($this->tests as &$test) { + foreach ($test as $key => $value) { + $test[$key] = rtrim($value, "\n"); + } + } + } + + /** + * Converts a DOMDocument into string form as seen in test cases. + */ + public static function strDom($node, $prefix = '| ') { + // XXX: Doesn't handle svg and math correctly + $ret = array(); + $indent = 2; + $level = -1; // since DOMDocument doesn't get rendered + $skip = false; + $next = $node; + while ($next) { + if ($next instanceof DOMNodeList) { + if (!$next->length) break; + $next = $next->item(0); + $level = 0; + } + $text = false; + $subnodes = array(); + switch ($next->nodeType) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + if ($next->doctype) { + $subnode = '<!DOCTYPE '; + $subnode .= $next->doctype->name; + if ($next->doctype->publicId || $next->doctype->systemId) { + $subnode .= ' "' . $next->doctype->publicId . '"'; + $subnode .= ' "' . $next->doctype->systemId . '"'; + } + $subnode .= '>'; + $subnodes[] = $subnode; + } elseif (!empty($next->emptyDoctype)) { + $subnodes = array('<!DOCTYPE >'); + } + break; + case XML_TEXT_NODE: + $text = '"' . $next->data . '"'; + break; + case XML_COMMENT_NODE: + $text = "<!-- {$next->data} -->"; + break; + case XML_ELEMENT_NODE: + $ns = ''; + switch ($next->namespaceURI) { + case HTML5_TreeBuilder::NS_MATHML: + $ns = 'math '; break; + case HTML5_TreeBuilder::NS_SVG: + $ns = 'svg '; break; + } + $text = "<{$ns}{$next->tagName}>"; + foreach ($next->attributes as $attr) { + $ans = ''; + switch ($attr->namespaceURI) { + case HTML5_TreeBuilder::NS_MATHML: + $ans = 'math '; break; + case HTML5_TreeBuilder::NS_SVG: + $ans = 'svg '; break; + case HTML5_TreeBuilder::NS_XLINK: + $ans = 'xlink '; break; + case HTML5_TreeBuilder::NS_XML: + $ans = 'xml '; break; + case HTML5_TreeBuilder::NS_XMLNS: + $ans = 'xmlns '; break; + } + // XSKETCHY: needed for our horrible xlink hack + $name = str_replace(':', ' ', $attr->localName); + $subnodes[] = "{$ans}{$name}=\"{$attr->value}\""; + } + sort($subnodes); + break; + } + if (!$skip) { + // code duplication + if ($text) { + $ret[] = $prefix . str_repeat(' ', $indent * $level) . $text; + } + foreach ($subnodes as $node) { + $ret[] = $prefix . str_repeat(' ', $indent * ($level + 1)) . $node; + } + } + if ($next->firstChild && !$skip) { + $next = $next->firstChild; + $level++; + $skip = false; + } elseif ($next->nextSibling) { + $next = $next->nextSibling; + $skip = false; + } elseif ($next->parentNode) { + $next = $next->parentNode; + $level--; + $skip = true; + if ($level < 0) break; + } else { + $next = false; + } + } + return implode("\n", $ret); + } +} diff --git a/test/SimpleTest/HTML5/TestDataHarness.php b/test/SimpleTest/HTML5/TestDataHarness.php new file mode 100644 index 0000000..0b90321 --- /dev/null +++ b/test/SimpleTest/HTML5/TestDataHarness.php @@ -0,0 +1,18 @@ +<?php + +SimpleTest::ignore('HTML5_TestDataHarness'); +abstract class HTML5_TestDataHarness extends HTML5_DataHarness +{ + protected $data; + public function __construct() { + parent::__construct(); + $this->data = new HTML5_TestData($this->filename); + } + public function getDescription($test) { + return $test['data']; + } + public function getDataTests() { + return $this->data->tests; + } +} + diff --git a/test/SimpleTest/HTML5/TestDataTest.php b/test/SimpleTest/HTML5/TestDataTest.php new file mode 100644 index 0000000..de97040 --- /dev/null +++ b/test/SimpleTest/HTML5/TestDataTest.php @@ -0,0 +1,31 @@ +<?php + +require_once dirname(__FILE__) . '/../autorun.php'; + +class HTML5_TestDataTest extends UnitTestCase +{ + function testSample() { + $data = new HTML5_TestData(dirname(__FILE__) . '/TestDataTest/sample.dat'); + $this->assertIdentical($data->tests, array( + array('data' => "Foo", 'des' => "Bar"), + array('data' => "Foo") + )); + } + function testStrDom() { + $dom = new DOMDocument(); + $dom->loadHTML('<!DOCTYPE html PUBLIC "http://foo" "http://bar"><html><body foo="bar" baz="1">foo<b>bar</b>asdf</body></html>'); + $this->assertIdentical(HTML5_TestData::strDom($dom), <<<RESULT +| <!DOCTYPE html "http://foo" "http://bar"> +| <html> +| <body> +| baz="1" +| foo="bar" +| "foo" +| <b> +| "bar" +| "asdf" +RESULT +); + } +} + diff --git a/test/SimpleTest/HTML5/TestDataTest/sample.dat b/test/SimpleTest/HTML5/TestDataTest/sample.dat new file mode 100644 index 0000000..4351e8d --- /dev/null +++ b/test/SimpleTest/HTML5/TestDataTest/sample.dat @@ -0,0 +1,7 @@ +#data +Foo +#des +Bar + +#data +Foo |