summaryrefslogtreecommitdiff
path: root/test/SimpleTest
diff options
context:
space:
mode:
Diffstat (limited to 'test/SimpleTest')
-rw-r--r--test/SimpleTest/HTML5/DataHarness.php48
-rw-r--r--test/SimpleTest/HTML5/JSONHarness.php21
-rw-r--r--test/SimpleTest/HTML5/TestData.php167
-rw-r--r--test/SimpleTest/HTML5/TestDataHarness.php18
-rw-r--r--test/SimpleTest/HTML5/TestDataTest.php31
-rw-r--r--test/SimpleTest/HTML5/TestDataTest/sample.dat7
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