summaryrefslogtreecommitdiff
path: root/_test/lib
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2005-10-15 13:45:45 +0200
committerAndreas Gohr <andi@splitbrain.org>2005-10-15 13:45:45 +0200
commitb73cc7dccaa01778de20ade004e0c3bde2e2e36a (patch)
treea082fedea2f4a7e99b5cc6352c35e9b192b145ec /_test/lib
parent5e35ae2a19fba9e79a1b71d951d7f322b864c001 (diff)
downloadrpg-b73cc7dccaa01778de20ade004e0c3bde2e2e36a.tar.gz
rpg-b73cc7dccaa01778de20ade004e0c3bde2e2e36a.tar.bz2
renamed test directory
darcs-hash:20051015114545-7ad00-561552ce7e519d81146b5cb2d28203aee7c6d2ad.gz
Diffstat (limited to '_test/lib')
-rw-r--r--_test/lib/cli_reporter.php91
-rw-r--r--_test/lib/rss_writer_class.php369
-rw-r--r--_test/lib/testmanager.php476
-rw-r--r--_test/lib/web.inc.php47
-rw-r--r--_test/lib/xml_writer_class.php292
5 files changed, 1275 insertions, 0 deletions
diff --git a/_test/lib/cli_reporter.php b/_test/lib/cli_reporter.php
new file mode 100644
index 000000000..a65112a34
--- /dev/null
+++ b/_test/lib/cli_reporter.php
@@ -0,0 +1,91 @@
+<?php // -*- fill-column: 80; tab-width: 4; c-basic-offset: 4 -*-
+
+if (! defined('ST_FAILDETAIL_SEPARATOR')) {
+ define('ST_FAILDETAIL_SEPARATOR', "->");
+}
+
+if (! defined('ST_FAILS_RETURN_CODE')) {
+ define('ST_FAILS_RETURN_CODE', 1);
+}
+
+if (version_compare(phpversion(), '4.3.0', '<') ||
+ php_sapi_name() == 'cgi') {
+ define('STDOUT', fopen('php://stdout', 'w'));
+ define('STDERR', fopen('php://stderr', 'w'));
+ register_shutdown_function(
+ create_function('', 'fclose(STDOUT); fclose(STDERR); return true;'));
+}
+
+/**
+ * Minimal command line test displayer. Writes fail details to STDERR. Returns 0
+ * to the shell if all tests pass, ST_FAILS_RETURN_CODE if any test fails.
+ */
+class CLIReporter extends SimpleReporter {
+
+ var $faildetail_separator = ST_FAILDETAIL_SEPARATOR;
+
+ function CLIReporter($faildetail_separator = NULL) {
+ $this->SimpleReporter();
+ if (! is_null($faildetail_separator)) {
+ $this->setFailDetailSeparator($faildetail_separator);
+ }
+ }
+
+ function setFailDetailSeparator($separator) {
+ $this->faildetail_separator = $separator;
+ }
+
+ /**
+ * Return a formatted faildetail for printing.
+ */
+ function &_paintTestFailDetail(&$message) {
+ $buffer = '';
+ $faildetail = $this->getTestList();
+ array_shift($faildetail);
+ $buffer .= implode($this->faildetail_separator, $faildetail);
+ $buffer .= $this->faildetail_separator . "$message\n";
+ return $buffer;
+ }
+
+ /**
+ * Paint fail faildetail to STDERR.
+ */
+ function paintFail($message) {
+ parent::paintFail($message);
+ fwrite(STDERR, 'FAIL' . $this->faildetail_separator .
+ $this->_paintTestFailDetail($message));
+ }
+
+ /**
+ * Paint exception faildetail to STDERR.
+ */
+ function paintException($message) {
+ parent::paintException($message);
+ fwrite(STDERR, 'EXCEPTION' . $this->faildetail_separator .
+ $this->_paintTestFailDetail($message));
+ }
+
+ /**
+ * Paint a footer with test case name, timestamp, counts of fails and
+ * exceptions.
+ */
+ function paintFooter($test_name) {
+ $buffer = $this->getTestCaseProgress() . '/' .
+ $this->getTestCaseCount() . ' test cases complete: ';
+
+ if (0 < ($this->getFailCount() + $this->getExceptionCount())) {
+ $buffer .= $this->getPassCount() . " passes";
+ if (0 < $this->getFailCount()) {
+ $buffer .= ", " . $this->getFailCount() . " fails";
+ }
+ if (0 < $this->getExceptionCount()) {
+ $buffer .= ", " . $this->getExceptionCount() . " exceptions";
+ }
+ $buffer .= ".\n";
+ fwrite(STDOUT, $buffer);
+ exit(ST_FAILS_RETURN_CODE);
+ } else {
+ fwrite(STDOUT, $buffer . $this->getPassCount() . " passes.\n");
+ }
+ }
+}
diff --git a/_test/lib/rss_writer_class.php b/_test/lib/rss_writer_class.php
new file mode 100644
index 000000000..684acfcfa
--- /dev/null
+++ b/_test/lib/rss_writer_class.php
@@ -0,0 +1,369 @@
+<?php
+if(!defined("METAL_LIBRARY_XML_RSS_WRITER_CLASS"))
+{
+ define("METAL_LIBRARY_XML_RSS_WRITER_CLASS",1);
+
+/*
+ *
+ * Copyright � (C) Manuel Lemos 2002
+ *
+ * @(#) $Id: rss_writer_class.php,v 1.5 2005/08/20 09:46:06 pachanga Exp $
+ *
+ */
+
+class rss_writer_class extends xml_writer_class
+{
+ /*
+ * Protected variables
+ *
+ */
+ var $root="";
+ var $channel="";
+ var $image="";
+ var $textinput="";
+ var $items=0;
+ var $itemsequence="";
+
+ /*
+ * Public variables
+ *
+ */
+ var $specification="1.0";
+ var $about="";
+ var $rssnamespaces=array();
+ var $allownoitems=0;
+ var $generatedcomment="Generated by: http://www.phpclasses.org/rsswriter";
+
+
+ /*
+ * Protected functions
+ *
+ */
+ Function addrssproperties(&$properties,$parent,&$required,&$optional,$scope)
+ {
+ $noattributes=array();
+ $required_properties=0;
+ Reset($properties);
+ $end=(GetType($property=Key($properties))!="string");
+ for(;!$end;)
+ {
+ if(IsSet($required[$property]))
+ {
+ if($required[$property])
+ {
+ $this->error=("required ".$scope." property \"".$property."\" is already set");
+ return 0;
+ }
+ $required[$property]=1;
+ $required_properties++;
+ }
+ else
+ {
+ if(IsSet($optional[$property]))
+ {
+ if($optional[$property])
+ {
+ $this->error=("optional ".$scope." property \"".$property."\" is already set");
+ return 0;
+ }
+ $optional[$property]=1;
+ }
+ else
+ {
+ if(GetType($colon=strpos($property,":",0))=="integer")
+ {
+ $namespace=substr($property,0,$colon);
+ if(!(!strcmp($namespace,"rdf") || IsSet($this->rssnamespaces[$namespace])))
+ $this->error=("the name space of property \"".$property."\" was not declared");
+ }
+ else
+ $this->error=("\"".$property."\" is not a supported ".$scope." property");
+ }
+ }
+ if(!($this->adddatatag($property,$noattributes,$properties[$property],$parent,$path)))
+ return 0;
+ Next($properties);
+ $end=(GetType($property=Key($properties))!="string");
+ }
+ if($required_properties<count($required))
+ {
+ Reset($required);
+ $end=(GetType($property=Key($required))!="string");
+ for(;!$end;)
+ {
+ if(!($required[$property]))
+ {
+ $this->error=("it was not specified the required ".$scope." property \"".$property."\"");
+ return 0;
+ }
+ Next($required);
+ $end=(GetType($property=Key($required))!="string");
+ }
+ }
+ return 1;
+ }
+
+ /*
+ * Public functions
+ *
+ */
+ Function addchannel(&$properties)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(strcmp($this->channel,""))
+ {
+ $this->error="a channel was already added";
+ return 0;
+ }
+ $channel_attributes=array();
+ switch($this->specification)
+ {
+ case "0.9":
+ $root="rdf:RDF";
+ $attributes=array("xmlns:rdf"=>"http://www.w3.org/1999/02/22-rdf-syntax-ns#","xmlns"=>"http://my.netscape.com/rdf/simple/0.9/");
+ $required=array("description"=>0,"link"=>0,"title"=>0);
+ $optional=array();
+ break;
+ case "0.91":
+ $root="rss";
+ $attributes=array("version"=>$this->specification);
+ $required=array("description"=>0,"language"=>0,"link"=>0,"title"=>0);
+ $optional=array("copyright"=>0,"docs"=>0,"lastBuildDate"=>0,"managingEditor"=>0,"pubDate"=>0,"rating"=>0,"webMaster"=>0);
+ break;
+ case "1.0":
+ if(!strcmp($this->about,""))
+ {
+ $this->error="it was not specified the about URL attribute";
+ return 0;
+ }
+ $root="rdf:RDF";
+ $attributes=array("xmlns:rdf"=>"http://www.w3.org/1999/02/22-rdf-syntax-ns#","xmlns"=>"http://purl.org/rss/1.0/");
+ Reset($this->rssnamespaces);
+ $end=(GetType($namespace=Key($this->rssnamespaces))!="string");
+ for(;!$end;)
+ {
+ if(!strcmp($namespace,"rdf"))
+ {
+ $this->error="the rdf namespace is being redeclared";
+ return 0;
+ }
+ $attributes[("xmlns:".$namespace)]=$this->rssnamespaces[$namespace];
+ Next($this->rssnamespaces);
+ $end=(GetType($namespace=Key($this->rssnamespaces))!="string");
+ }
+ $channel_attributes=array("rdf:about"=>$this->about);
+ $required=array("description"=>0,"link"=>0,"title"=>0);
+ $optional=array();
+ break;
+ default:
+ $this->error="it was not specified a supported RSS specification version";
+ return 0;
+ }
+ $this->addtag($root,$attributes,"",$path,1);
+ $this->root=$path;
+ if(!($this->addtag("channel",$channel_attributes,$this->root,$path,1)))
+ return 0;
+ if(!($this->addrssproperties($properties,$path,$required,$optional,"channel")))
+ return 0;
+ $this->channel=$path;
+ return 1;
+ }
+
+ Function additem(&$properties)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(!strcmp($this->channel,""))
+ {
+ $this->error="the channel was not yet added";
+ return 0;
+ }
+ if(strcmp($this->textinput,""))
+ {
+ $this->error="items can not be added to the channel after defining the textinput";
+ return 0;
+ }
+ $attributes=array();
+ switch($this->specification)
+ {
+ case "0.9":
+ $parent=$this->root;
+ break;
+ case "0.91":
+ $parent=$this->channel;
+ break;
+ case "1.0":
+ if(IsSet($properties["link"]))
+ $attributes["rdf:about"]=$properties["link"];
+ $parent=$this->root;
+ break;
+ default:
+ $this->error="it was not specified a supported RSS specification version";
+ return 0;
+ }
+ if(!($this->addtag("item",$attributes,$parent,$path,1)))
+ return 0;
+ $required=array("link"=>0,"title"=>0);
+ $optional=array("description"=>0);
+ if(!($this->addrssproperties($properties,$path,$required,$optional,"item")))
+ return 0;
+ if(!strcmp($this->specification,"1.0"))
+ {
+ if(!strcmp($this->itemsequence,""))
+ {
+ $attributes=array();
+ if(!($this->addtag("items",$attributes,$this->channel,$path,1) && $this->addtag("rdf:Seq",$attributes,$path,$path,1)))
+ return 0;
+ $this->itemsequence=$path;
+ }
+ $attributes=array("rdf:resource"=>$properties["link"]);
+ if(!($this->addtag("rdf:li",$attributes,$this->itemsequence,$path,0)))
+ return 0;
+ }
+ $this->items++;
+ return 1;
+ }
+
+ Function addimage(&$properties)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(!strcmp($this->channel,""))
+ {
+ $this->error="the channel was not yet added";
+ return 0;
+ }
+ if(strcmp($this->image,""))
+ {
+ $this->error="the channel image was already associated";
+ return 0;
+ }
+ if($this->items!=0)
+ {
+ $this->error="the image can only be defined before adding the channel items";
+ return 0;
+ }
+ $attributes=array();
+ switch($this->specification)
+ {
+ case "0.9":
+ $parent=$this->root;
+ break;
+ case "0.91":
+ $parent=$this->channel;
+ break;
+ case "1.0":
+ if(IsSet($properties["url"]))
+ $attributes["rdf:about"]=$properties["url"];
+ $parent=$this->root;
+ break;
+ default:
+ $this->error="it was not specified a supported RSS specification version";
+ return 0;
+ }
+ if(!($this->addtag("image",$attributes,$parent,$path,1)))
+ return 0;
+ $this->image=$path;
+ $required=array("link"=>0,"title"=>0,"url"=>0);
+ $optional=array("description"=>0,"width"=>0,"height"=>0);
+ if(!($this->addrssproperties($properties,$this->image,$required,$optional,"image")))
+ return 0;
+ if(!strcmp($this->specification,"1.0"))
+ {
+ $attributes=array("rdf:resource"=>$properties["url"]);
+ return $this->addtag("image",$attributes,$this->channel,$path,0);
+ }
+ return 1;
+ }
+
+ Function addtextinput(&$properties)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(!strcmp($this->channel,""))
+ {
+ $this->error="the channel was not yet added";
+ return 0;
+ }
+ if(strcmp($this->textinput,""))
+ {
+ $this->error="the channel text input was already associated";
+ return 0;
+ }
+ if($this->items==0 && !$this->allownoitems)
+ {
+ $this->error="it were not specified any items before defining the channel text input";
+ return 0;
+ }
+ $attributes=array();
+ switch($this->specification)
+ {
+ case "0.9":
+ $parent=$this->root;
+ break;
+ case "0.91":
+ $parent=$this->channel;
+ break;
+ case "1.0":
+ if(IsSet($properties["link"]))
+ $attributes["rdf:about"]=$properties["link"];
+ $parent=$this->root;
+ break;
+ default:
+ $this->error="it was not specified a supported RSS specification version";
+ return 0;
+ }
+ if(!($this->addtag("textinput",$attributes,$parent,$path,1)))
+ return 0;
+ $this->textinput=$path;
+ $required=array("description"=>0,"link"=>0,"name"=>0,"title"=>0);
+ $optional=array();
+ if(!($this->addrssproperties($properties,$this->textinput,$required,$optional,"textinput")))
+ return 0;
+ if(!strcmp($this->specification,"1.0"))
+ {
+ $attributes=array("rdf:resource"=>$properties["link"]);
+ return $this->addtag("textinput",$attributes,$this->channel,$path,0);
+ }
+ return 1;
+ }
+
+ Function writerss(&$output)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(!strcmp($this->channel,""))
+ {
+ $this->error="it was not defined the RSS channel";
+ return 0;
+ }
+ if($this->items==0 && !$this->allownoitems)
+ {
+ $this->error="it were not defined any RSS channel items";
+ return 0;
+ }
+ switch($this->specification)
+ {
+ case "0.9":
+ $this->dtdtype="PUBLIC";
+ $this->dtddefinition="-//Netscape Communications//DTD RSS 0.9//EN";
+ $this->dtdurl="http://my.netscape.com/publish/formats/rss-0.9.dtd";
+ break;
+ case "0.91":
+ $this->dtdtype="PUBLIC";
+ $this->dtddefinition="-//Netscape Communications//DTD RSS 0.91//EN";
+ $this->dtdurl="http://my.netscape.com/publish/formats/rss-0.91.dtd";
+ break;
+ case "1.0":
+ $this->dtdtype="";
+ break;
+ default:
+ $this->error="it was not specified a supported RSS specification version";
+ return 0;
+ }
+ return $this->write($output);
+ }
+};
+
+}
diff --git a/_test/lib/testmanager.php b/_test/lib/testmanager.php
new file mode 100644
index 000000000..9fb73daf6
--- /dev/null
+++ b/_test/lib/testmanager.php
@@ -0,0 +1,476 @@
+<?php // -*- fill-column: 80; tab-width: 4; c-basic-offset: 4 -*-
+/**
+* Lots TODO here...
+*/
+
+define('TEST_GROUPS',realpath(dirname(__FILE__).'/../cases'));
+define('TEST_CASES',realpath(dirname(__FILE__).'/../cases'));
+
+class TestManager {
+ var $_testcase_extension = '.test.php';
+ var $_grouptest_extension = '.group.php';
+
+ function setup() {
+ $ini_file = realpath(dirname(__FILE__).'/../tests.ini');
+
+ if (! file_exists($ini_file)) {
+ trigger_error("Missing configuration file {$ini_file}",
+ E_USER_ERROR);
+ }
+ $config = parse_ini_file($ini_file);
+ foreach ($config as $key => $value) {
+ define($key, $value);
+ }
+ TestManager::_installSimpleTest();
+ }
+
+ function _installSimpleTest() {
+ require_once SIMPLE_TEST . 'unit_tester.php';
+ require_once SIMPLE_TEST . 'web_tester.php';
+ require_once SIMPLE_TEST . 'mock_objects.php';
+ require_once 'web.inc.php';
+ }
+
+ function runAllTests(&$reporter) {
+ $manager =& new TestManager();
+ $test_cases =& $manager->_getTestFileList();
+ $test =& new GroupTest('All Tests');
+ foreach ($test_cases as $test_case) {
+ $test->addTestFile($test_case);
+ }
+ $test->run($reporter);
+ }
+
+ function runTestCase($testcase_name, $test_case_directory, &$reporter) {
+ $manager =& new TestManager();
+
+ $testcase_name = preg_replace('/[^a-zA-Z0-9_:]/','',$testcase_name);
+ $testcase_name = str_replace(':',DIRECTORY_SEPARATOR,$testcase_name);
+
+ $testcase_file = $test_case_directory . DIRECTORY_SEPARATOR .
+ strtolower($testcase_name) . $manager->_testcase_extension;
+
+ if (! file_exists($testcase_file)) {
+ trigger_error("Test case {$testcase_file} cannot be found",
+ E_USER_ERROR);
+ }
+
+ $test =& new GroupTest("Individual test case: " . $testcase_name);
+ $test->addTestFile($testcase_file);
+ $test->run($reporter);
+ }
+
+ function runTestFile($testcase_file, &$reporter) {
+ $manager =& new TestManager();
+
+ if (! file_exists($testcase_file)) {
+ trigger_error("Test case {$testcase_file} cannot be found",
+ E_USER_ERROR);
+ }
+
+ $test =& new GroupTest("Individual test case: " . $testcase_file);
+ $test->addTestFile($testcase_file);
+ $test->run($reporter);
+ }
+
+ function runGroupTest($group_test_name, $group_test_directory, &$reporter) {
+ $manager =& new TestManager();
+ $group_test_name = preg_replace('/[^a-zA-Z0-9_:]/','',$group_test_name);
+ $group_test_name = str_replace(':',DIRECTORY_SEPARATOR,$group_test_name);
+ $file_path = $group_test_directory . DIRECTORY_SEPARATOR .
+ strtolower($group_test_name) . $manager->_grouptest_extension;
+
+ if (! file_exists($file_path)) {
+ trigger_error("Group test {$group_test_name} cannot be found at {$file_path}",
+ E_USER_ERROR);
+ }
+
+ require_once $file_path;
+ $test =& new GroupTest($group_test_name . ' group test');
+ foreach ($manager->_getGroupTestClassNames($file_path) as $group_test) {
+ $test->addTestCase(new $group_test());
+ }
+ $test->run($reporter);
+ }
+
+ function addTestCasesFromDirectory(&$group_test, $directory = '.') {
+ $manager =& new TestManager();
+ $test_cases =& $manager->_getTestFileList($directory);
+ foreach ($test_cases as $test_case) {
+ $group_test->addTestFile($test_case);
+ }
+ }
+
+ function &getTestCaseList($directory = '.') {
+ $manager =& new TestManager();
+ return $manager->_getTestCaseList($directory);
+ }
+
+ function &_getTestCaseList($directory = '.') {
+ $base = TEST_GROUPS . DIRECTORY_SEPARATOR;
+ $file_list =& $this->_getTestFileList($directory);
+ $testcases = array();
+ foreach ($file_list as $testcase_file) {
+ $case = str_replace($this->_testcase_extension, '',$testcase_file);
+ $case = str_replace($base, '', $case);
+ $case = str_replace(DIRECTORY_SEPARATOR, ':', $case);
+ $testcases[$testcase_file] = $case;
+ }
+ return $testcases;
+ }
+
+ function &_getTestFileList($directory = '.') {
+ return $this->_getRecursiveFileList($directory,
+ array(&$this, '_isTestCaseFile'));
+ }
+
+ function &getGroupTestList($directory = '.') {
+ $manager =& new TestManager();
+ return $manager->_getTestGroupList($directory);
+ }
+
+ function &_getTestGroupFileList($directory = '.') {
+ return $this->_getRecursiveFileList($directory,
+ array(&$this, '_isTestGroupFile'));
+ }
+
+ function &_getTestGroupList($directory = '.') {
+ $base = TEST_GROUPS . DIRECTORY_SEPARATOR;
+ $file_list =& $this->_getTestGroupFileList($directory);
+ $grouptests = array();
+ foreach ($file_list as $grouptest_file) {
+ $group = str_replace($this->_grouptest_extension, '',$grouptest_file);
+ $group = str_replace($base, '', $group);
+ $group = str_replace(DIRECTORY_SEPARATOR, ':', $group);
+ $grouptests[$grouptest_file] = $group;
+ }
+ sort($grouptests);
+ return $grouptests;
+ }
+
+ function &_getGroupTestClassNames($grouptest_file) {
+ $file = implode("\n", file($grouptest_file));
+ preg_match("~lass\s+?(.*)\s+?extends GroupTest~", $file, $matches);
+ if (! empty($matches)) {
+ unset($matches[0]);
+ return $matches;
+ } else {
+ return array();
+ }
+ }
+
+ function &_getRecursiveFileList($directory = '.', $file_test_function) {
+ $dh = opendir($directory);
+ if (! is_resource($dh)) {
+ trigger_error("Couldn't open {$directory}", E_USER_ERROR);
+ }
+
+ $file_list = array();
+ while ($file = readdir($dh)) {
+ $file_path = $directory . DIRECTORY_SEPARATOR . $file;
+
+ if (0 === strpos($file, '.')) continue;
+
+ if (is_dir($file_path)) {
+ $file_list =
+ array_merge($file_list,
+ $this->_getRecursiveFileList($file_path,
+ $file_test_function));
+ }
+ if ($file_test_function[0]->$file_test_function[1]($file)) {
+ $file_list[] = $file_path;
+ }
+ }
+ closedir($dh);
+ return $file_list;
+ }
+
+ function _isTestCaseFile($file) {
+ return $this->_hasExpectedExtension($file, $this->_testcase_extension);
+ }
+
+ function _isTestGroupFile($file) {
+ return $this->_hasExpectedExtension($file, $this->_grouptest_extension);
+ }
+
+ function _hasExpectedExtension($file, $extension) {
+ return $extension ==
+ strtolower(substr($file, (0 - strlen($extension))));
+ }
+}
+
+/**
+* @package WACT_TESTS
+*/
+class CLITestManager extends TestManager {
+ function &getGroupTestList($directory = '.') {
+ $manager =& new CLITestManager();
+ $group_tests =& $manager->_getTestGroupList($directory);
+
+ $buffer = "Available grouptests:\n";
+ foreach ($group_tests as $group_test) {
+ $buffer .= " " . $group_test . "\n";
+ }
+ return $buffer . "\n";
+ }
+
+ function &getTestCaseList($directory = '.') {
+ $manager =& new CLITestManager();
+ $test_cases =& $manager->_getTestCaseList($directory);
+
+ $buffer = "Available test cases:\n";
+ foreach ($test_cases as $test_case) {
+ $buffer .= " " . $test_case . "\n";
+ }
+ return $buffer . "\n";
+ }
+}
+
+class HTMLTestManager extends TestManager {
+ var $_url;
+
+ function HTMLTestManager() {
+ $this->_url = $_SERVER['PHP_SELF'];
+ }
+
+ function getBaseURL() {
+ return $this->_url;
+ }
+
+ function &getGroupTestList($directory = '.') {
+ $manager =& new HTMLTestManager();
+ $group_tests =& $manager->_getTestGroupList($directory);
+ if (1 > count($group_tests)) {
+ return "<p>No test groups set up!</p>";
+ }
+ $buffer = "<p>Available test groups:</p>\n<ul>";
+ $buffer .= "<li><a href='" . $manager->getBaseURL() . "?group=all'>All tests</a></li>\n";
+ foreach ($group_tests as $group_test) {
+ $buffer .= "<li><a href='" . $manager->getBaseURL() . "?group={$group_test}'>" .
+ $group_test . "</a></li>\n";
+ }
+ return $buffer . "</ul>\n";
+ }
+
+ function &getTestCaseList($directory = '.') {
+ $manager =& new HTMLTestManager();
+ $testcases =& $manager->_getTestCaseList($directory);
+
+ if (1 > count($testcases)) {
+ return "<p>No test cases set up!</p>";
+ }
+ $buffer = "<p>Available test cases:</p>\n<ul>";
+ foreach ($testcases as $testcase) {
+ $buffer .= "<li><a href='" . $manager->getBaseURL() .
+ "?case=" . urlencode($testcase) . "'>" .
+ $testcase . "</a></li>\n";
+ }
+ return $buffer . "</ul>\n";
+ }
+}
+
+/**
+* @package WACT_TESTS
+*/
+class XMLTestManager extends HTMLTestManager {
+
+ function XMLTestManager() {
+ parent::HTMLTestManager();
+ }
+
+ function &getGroupTestList($directory = '.') {
+
+ $manager =& new XMLTestManager();
+ $group_tests =& $manager->_getTestGroupList($directory);
+
+ $rss = & $manager->_getRssWriter();
+
+ if (1 > count($group_tests)) {
+ $rss->writeRss($output);
+ return $output;
+ }
+
+ $properties["title"]="All Tests";
+ $properties["description"]="All Tests";
+ $properties["link"]='http://'.$_SERVER['SERVER_NAME'].
+ $manager->getBaseURL()."?group=all&output=xml";
+
+ $rss->additem($properties);
+
+ foreach ($group_tests as $group_test) {
+ $properties["title"]=$group_test;
+ $properties["description"]=$group_test;
+ $properties["link"]='http://'.$_SERVER['SERVER_NAME'].
+ $manager->getBaseURL().
+ "?group={$group_test}&output=xml";
+
+ $rss->additem($properties);
+ }
+ if ( !$rss->writeRss($output) ) {
+ die ( $rss->error );
+ }
+ return $output;
+
+ }
+
+ function &getTestCaseList($directory = '.') {
+
+ $manager =& new XMLTestManager();
+ $testcases =& $manager->_getTestCaseList($directory);
+
+ $rss = & $manager->_getRssWriter();
+
+ if (1 > count($testcases)) {
+ $rss->writeRss($output);
+ return $output;
+ }
+
+ foreach ($testcases as $testfile => $testcase) {
+ $properties["title"]=$testcase;
+ $properties["description"]=$testcase;
+ $properties["link"]='http://'.$_SERVER['SERVER_NAME'].
+ $manager->getBaseURL()."?case=" .
+ urlencode($testcase) . "&output=xml";
+
+ // Comment this out for performance?
+ $properties["dc:date"]=gmdate("Y-m-d\TH:i:sO",filemtime($testfile));
+
+ $rss->additem($properties);
+ }
+
+ $rss->writeRss($output);
+ return $output;
+ }
+
+ function &_getRssWriter() {
+
+ $url = 'http://'.$_SERVER['SERVER_NAME'].str_replace('index.php','',$_SERVER['PHP_SELF']);
+
+ require_once TEST_ROOT . '/lib/xml_writer_class.php';
+ require_once TEST_ROOT . '/lib/rss_writer_class.php';
+
+ $rss_writer_object=& new rss_writer_class();
+ $rss_writer_object->specification="1.0";
+ $rss_writer_object->about=$url."index.php?output=xml";
+ $rss_writer_object->stylesheet=$url."rss2html.xsl";
+ $rss_writer_object->rssnamespaces["dc"]="http://purl.org/dc/elements/1.1/";
+
+ // Channel Properties
+ $properties=array();
+ $properties["title"]="Dokuwiki Unit Test Cases";
+ $properties["description"]="Dokuwiki Unit Test Cases";
+ $properties["link"]="http://wiki.splitbrain.org/";
+ $properties["dc:date"]=gmdate("Y-m-d\TH:i:sO");
+ $rss_writer_object->addchannel($properties);
+
+ // Logo like this (if we had one)
+ /*
+ $properties=array();
+
+ $properties["link"]="http://www.phpclasses.org/";
+ $properties["title"]="PHP Classes repository logo";
+ $properties["description"]="Repository of components and other resources for PHP developers";
+ $rss_writer_object->addimage($properties);
+ */
+
+ return $rss_writer_object;
+ }
+
+}
+
+/**
+* @package WACT_TESTS
+*/
+class RemoteTestManager extends TestManager {
+
+ function RemoteTestManager() {
+ RemoteTestManager::_installSimpleTest();
+ }
+
+ function _installSimpleTest() {
+ require_once SIMPLE_TEST . 'remote.php';
+ }
+
+ function runAllTests(&$reporter, $url = FALSE) {
+ $groups = RemoteTestManager::getGroupTestList($url);
+ $T = &new RemoteTestCase($groups['All Tests']);
+ $T->run($reporter);
+ }
+
+ function runTestUrl($case_url,& $reporter, $url = FALSE) {
+ RemoteTestManager::_installSimpleTest();
+ $T = &new RemoteTestCase($case_url);
+ $T->run($reporter);
+ }
+
+ function runTestCase($case_id,& $reporter, $url = FALSE) {
+ $cases = RemoteTestManager::getTestCaseList($url);
+ if ( !array_key_exists($case_id, $cases) ) {
+ trigger_error("Unknown test id $case_id\n",E_USER_ERROR);
+ }
+ $T = &new RemoteTestCase($cases[$case_id]);
+ $T->run($reporter);
+ }
+
+ function runGroupTest($group_name, &$reporter, $url = FALSE) {
+ $groups = RemoteTestManager::getGroupTestList($url);
+ if ( !array_key_exists($group_name, $groups) ) {
+ trigger_error("Unknown group $group_name\n",E_USER_ERROR);
+ }
+ $T = &new RemoteTestCase($groups[$group_name]);
+ $T->run($reporter);
+ }
+
+ function & getGroupTestList($url = FALSE) {
+
+ if ( !$url ) {
+ $url = REMOTE_TEST_URL;
+ }
+
+ $url .= '?output=xml';
+
+ $manager =& new RemoteTestManager();
+ $rss = & $manager->_getRssReader($url);
+
+ $groupList = array();
+
+ foreach ($rss->getItems() as $item) {
+ $groupList[$item['title']] = $item['link'];
+ }
+
+ return $groupList;
+ }
+
+ function &getTestCaseList($url = FALSE) {
+ if ( !$url ) {
+ $url = REMOTE_TEST_URL;
+ }
+
+ $url .= '?show=cases&output=xml';
+ $manager =& new RemoteTestManager();
+ $rss = & $manager->_getRssReader($url);
+
+ $caseList = array();
+
+ foreach ($rss->getItems() as $item) {
+ $caseList[$item['title']] = $item['link'];
+ }
+
+ return $caseList;
+ }
+
+ function &_getRssReader($url) {
+ require_once "XML/RSS.php";
+
+ $rss_reader =& new XML_RSS($url);
+
+ $status = $rss_reader->parse();
+
+ if (PEAR::isError($status) ) {
+ trigger_error($status->getMessage(),E_USER_WARNING);
+ }
+
+ return $rss_reader;
+ }
+
+}
diff --git a/_test/lib/web.inc.php b/_test/lib/web.inc.php
new file mode 100644
index 000000000..7ca70f204
--- /dev/null
+++ b/_test/lib/web.inc.php
@@ -0,0 +1,47 @@
+<?php
+/**
+* @package WACT_TESTS
+* @version $Id: web.inc.php,v 1.6 2005/08/20 09:46:06 pachanga Exp $
+*/
+
+SimpleTestOptions::ignore('DWWebTestCase');
+
+class DWWebTestCase extends WebTestCase {
+
+ function assertNormalPage() {
+ $this->assertResponse(array(200));
+ $this->assertNoUnwantedPattern('/Warning:/i');
+ $this->assertNoUnwantedPattern('/Error:/i');
+ $this->assertNoUnwantedPattern('/Fatal error/i');
+ }
+
+ function assertWantedLiteral($str) {
+ $this->assertWantedPattern('/' . preg_quote($str, '/'). '/');
+ }
+
+ function assertNoUnWantedLiteral($str) {
+ $this->assertNoUnWantedPattern('/' . preg_quote($str, '/'). '/');
+ }
+
+ function &_fileToPattern($file) {
+ $file_as_array = file($file);
+ $pattern = '#^';
+ foreach ($file_as_array as $line) {
+ /* strip trailing newline */
+ if ($line[strlen($line) - 1] == "\n") {
+ $line = substr($line, 0, strlen($line) - 1);
+ }
+ $line = preg_quote($line, '#');
+
+ /* replace paths with wildcard */
+ $line = preg_replace("#'/[^']*#", "'.*", $line);
+
+ $pattern .= $line . '\n';
+ }
+ /* strip final newline */
+ $pattern = substr($pattern, 0, strlen($pattern) - 2);
+ $pattern .= '$#i';
+ return $pattern;
+ }
+
+}
diff --git a/_test/lib/xml_writer_class.php b/_test/lib/xml_writer_class.php
new file mode 100644
index 000000000..97fb1bee0
--- /dev/null
+++ b/_test/lib/xml_writer_class.php
@@ -0,0 +1,292 @@
+<?php
+if(!defined("METAL_LIBRARY_XML_XML_WRITER_CLASS"))
+{
+ define("METAL_LIBRARY_XML_XML_WRITER_CLASS",1);
+
+/*
+ *
+ * Copyright � (C) Manuel Lemos 2001-2002
+ *
+ * @(#) $Id: xml_writer_class.php,v 1.5 2005/08/20 09:46:06 pachanga Exp $
+ *
+ */
+
+class xml_writer_class
+{
+ /*
+ * Protected variables
+ *
+ */
+ var $structure=array();
+ var $nodes=array();
+
+ /*
+ * Public variables
+ *
+ */
+ var $stylesheet="";
+ var $stylesheettype="text/xsl";
+ var $dtdtype="";
+ var $dtddefinition="";
+ var $dtdurl="";
+ var $outputencoding="utf-8";
+ var $inputencoding="iso-8859-1";
+ var $linebreak="\n";
+ var $indenttext=" ";
+ var $generatedcomment="Generated by: http://www.phpclasses.org/xmlwriter";
+ var $error="";
+
+
+ /*
+ * Protected functions
+ *
+ */
+ Function escapedata($data)
+ {
+ $position=0;
+ $length=strlen($data);
+ $escapeddata="";
+ for(;$position<$length;)
+ {
+ $character=substr($data,$position,1);
+ $code=Ord($character);
+ switch($code)
+ {
+ case 34:
+ $character="&quot;";
+ break;
+ case 38:
+ $character="&amp;";
+ break;
+ case 39:
+ $character="&apos;";
+ break;
+ case 60:
+ $character="&lt;";
+ break;
+ case 62:
+ $character="&gt;";
+ break;
+ default:
+ if($code<32)
+ $character=("&#".strval($code).";");
+ break;
+ }
+ $escapeddata.=$character;
+ $position++;
+ }
+ return $escapeddata;
+ }
+
+ Function encodedata($data,&$encodeddata)
+ {
+ if(!strcmp($this->inputencoding,$this->outputencoding))
+ $encodeddata=$this->escapedata($data);
+ else
+ {
+ switch(strtolower($this->outputencoding))
+ {
+ case "utf-8":
+ if(!strcmp(strtolower($this->inputencoding),"iso-8859-1"))
+ {
+ $encoded_data=utf8_encode($this->escapedata($data));
+ $encodeddata=$encoded_data;
+ }
+ else
+ {
+ $this->error=("can not encode iso-8859-1 data in ".$this->outputencoding);
+ return 0;
+ }
+ break;
+ case "iso-8859-1":
+ if(!strcmp(strtolower($this->inputencoding),"utf-8"))
+ {
+ $decoded=utf8_decode($data);
+ $encodeddata=$this->escapedata($decoded);
+ }
+ else
+ {
+ $this->error=("can not encode utf-8 data in ".$this->outputencoding);
+ return 0;
+ }
+ break;
+ default:
+ $this->error=("can not encode data in ".$this->inputencoding);
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+ Function writetag(&$output,$path,$indent)
+ {
+ $tag=$this->structure[$path]["Tag"];
+ $output.=("<".$tag);
+ $attributecount=count($this->structure[$path]["Attributes"]);
+ if($attributecount>0)
+ {
+ $attributes=$this->structure[$path]["Attributes"];
+ Reset($attributes);
+ $end=(GetType($key=Key($attributes))!="string");
+ for(;!$end;)
+ {
+ $output.=(" ".$key."=\"".$attributes[$key]."\"");
+ Next($attributes);
+ $end=(GetType($key=Key($attributes))!="string");
+ }
+ }
+ $elements=$this->structure[$path]["Elements"];
+ if($elements>0)
+ {
+ $output.=">";
+ $doindent=$this->structure[$path]["Indent"];
+ $elementindent=(($doindent) ? $this->linebreak.$indent.$this->indenttext : "");
+ $element=0;
+ for(;$element<$elements;)
+ {
+ $elementpath=($path.",".strval($element));
+ $output.=$elementindent;
+ if(IsSet($this->nodes[$elementpath]))
+ {
+ if(!($this->writetag($output,$elementpath,$indent.$this->indenttext)))
+ return 0;
+ }
+ else
+ $output.=$this->structure[$elementpath];
+ $element++;
+ }
+ $output.=((($doindent) ? $this->linebreak.$indent : "")."</".$tag.">");
+ }
+ else
+ $output.="/>";
+ return 1;
+ }
+
+ /*
+ * Public functions
+ *
+ */
+ Function write(&$output)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(!(IsSet($this->structure["0"])))
+ {
+ $this->error="XML document structure is empty";
+ return 0;
+ }
+ $output=("<?xml version=\"1.0\" encoding=\"".$this->outputencoding."\"?>".$this->linebreak);
+ if(strcmp($this->dtdtype,""))
+ {
+ $output.=("<!DOCTYPE ".$this->structure["0"]["Tag"]." ");
+ switch($this->dtdtype)
+ {
+ case "INTERNAL":
+ if(!strcmp($this->dtddefinition,""))
+ {
+ $this->error="it was not specified a valid internal DTD definition";
+ return 0;
+ }
+ $output.=("[".$this->linebreak.$this->dtddefinition.$this->linebreak."]");
+ break;
+ case "SYSTEM":
+ if(!strcmp($this->dtdurl,""))
+ {
+ $this->error="it was not specified a valid system DTD url";
+ return 0;
+ }
+ $output.="SYSTEM";
+ if(strcmp($this->dtddefinition,""))
+ $output.=(" \"".$this->dtddefinition."\"");
+ $output.=(" \"".$this->dtdurl."\"");
+ break;
+ case "PUBLIC":
+ if(!strcmp($this->dtddefinition,""))
+ {
+ $this->error="it was not specified a valid public DTD definition";
+ return 0;
+ }
+ $output.=("PUBLIC \"".$this->dtddefinition."\"");
+ if(strcmp($this->dtdurl,""))
+ $output.=(" \"".$this->dtdurl."\"");
+ break;
+ default:
+ $this->error="it was not specified a valid DTD type";
+ return 0;
+ }
+ $output.=(">".$this->linebreak);
+ }
+ if(strcmp($this->stylesheet,""))
+ {
+ if(!strcmp($this->stylesheettype,""))
+ {
+ $this->error="it was not specified a valid stylesheet type";
+ return 0;
+ }
+ $output.=("<?xml-stylesheet type=\"".$this->stylesheettype."\" href=\"".$this->stylesheet."\"?>".$this->linebreak);
+ }
+ if(strcmp($this->generatedcomment,""))
+ $output.=("<!-- ".$this->generatedcomment." -->".$this->linebreak);
+ return $this->writetag($output,"0","");
+ }
+
+ Function addtag($tag,&$attributes,$parent,&$path,$indent)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ $path=((!strcmp($parent,"")) ? "0" : ($parent.",".strval($this->structure[$parent]["Elements"])));
+ if(IsSet($this->structure[$path]))
+ {
+ $this->error=("tag with path ".$path." is already defined");
+ return 0;
+ }
+ $encodedattributes=array();
+ Reset($attributes);
+ $end=(GetType($attribute_name=Key($attributes))!="string");
+ for(;!$end;)
+ {
+ $encodedattributes[$attribute_name]="";
+ if(!($this->encodedata($attributes[$attribute_name],$encoded_data)))
+ return 0;
+ $encodedattributes[$attribute_name]=$encoded_data;
+ Next($attributes);
+ $end=(GetType($attribute_name=Key($attributes))!="string");
+ }
+ $this->structure[$path]=array(
+ "Tag"=>$tag,
+ "Attributes"=>$encodedattributes,
+ "Elements"=>0,
+ "Indent"=>$indent
+ );
+ $this->nodes[$path]=1;
+ if(strcmp($parent,""))
+ $this->structure[$parent]["Elements"]=($this->structure[$parent]["Elements"]+1);
+ return 1;
+ }
+
+ Function adddata($data,$parent,&$path)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(!(IsSet($this->structure[$parent])))
+ {
+ $this->error=("the parent tag path".$path."is not defined");
+ return 0;
+ }
+ if(!strcmp($data,""))
+ return 1;
+ $path=($parent.",".strval($this->structure[$parent]["Elements"]));
+ if(!($this->encodedata($data,$encoded_data)))
+ return 0;
+ $this->structure[$path]=$encoded_data;
+ $this->structure[$parent]["Elements"]=($this->structure[$parent]["Elements"]+1);
+ return 1;
+ }
+
+ Function adddatatag($tag,&$attributes,$data,$parent,&$path)
+ {
+ return $this->addtag($tag,$attributes,$parent,$path,0) && $this->adddata($data,$path,$datapath);
+ }
+};
+
+}