summaryrefslogtreecommitdiff
path: root/_test
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
parent5e35ae2a19fba9e79a1b71d951d7f322b864c001 (diff)
downloadrpg-b73cc7dccaa01778de20ade004e0c3bde2e2e36a.tar.gz
rpg-b73cc7dccaa01778de20ade004e0c3bde2e2e36a.tar.bz2
renamed test directory
darcs-hash:20051015114545-7ad00-561552ce7e519d81146b5cb2d28203aee7c6d2ad.gz
Diffstat (limited to '_test')
-rw-r--r--_test/README84
-rw-r--r--_test/index.php173
-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
-rwxr-xr-x_test/remotetests.php163
-rw-r--r--_test/rss2html.xsl110
-rwxr-xr-x_test/runtests.php133
-rw-r--r--_test/tests.css27
-rw-r--r--_test/tests.ini12
-rwxr-xr-x_test/webtest-stripper.sh41
13 files changed, 2018 insertions, 0 deletions
diff --git a/_test/README b/_test/README
new file mode 100644
index 000000000..d651a4a82
--- /dev/null
+++ b/_test/README
@@ -0,0 +1,84 @@
+--------------------------------------------------------------------------------
+ Dokuwiki Unit Test Suite
+--------------------------------------------------------------------------------
+$Date: 2004/02/14 02:14:50 $
+
+Credits: to the WACT team - http://www.phpwact.org, from whom the basis of
+this test suite was stolen
+
+--------------------------------------------------------------------------------
+INSTALLING & SETUP
+
+1. Grab a copy of the SimpleTest unit testing framework an extract somewhere
+
+ http://www.lastcraft.com/simple_test.php
+ or
+ http://sourceforge.net/projects/simpletest
+
+2. Edit ./tests.ini
+
+ - TEST_ENABLED - set to "1" to allow the test suite to be used
+ by vistors to your site. Generally best to leave as 0 for
+ a productive site - running tests alot will hammer the server
+ Note: you will still be able to run the tests from the command
+ line even when this is set to 0
+
+ - WEB_TEST_URL - this is for running "web tests" where SimpleTest
+ acts as a web browser and executes HTTP requests against pages.
+ Should point at your Dokuwiki URL e.g.
+
+ http://localhost/dokuwiki
+
+ - PROXY - if you're behind a proxy, specify it here
+ Note: username / password are optional e.g.
+
+ http://proxyuser:proxypwd@proxy.yourdomain.com:8080
+
+ - REMOTE_TEST_URL - it's possible to run the full test suite
+ remotely (over HTTP) with some XML goodness. This should
+ point at the URL of the test suite you want to test
+ See the following URL for more info;
+ http://www.sitepoint.com/blogs/2004/06/15/simple-test-remote-testing/
+
+ - Simple Test
+ Update the library_path to point at the directory where you installed
+ Simple Test
+
+--------------------------------------------------------------------------------
+RUNNING THE TESTS
+
+You can run the tests in three ways. From the command line:
+
+ $ ./runtests.php -h
+
+Using a web browser;
+
+ http://localhost/dokuwiki/test/index.php
+
+As remote tests run on a remote serveri (specified in tests.ini with REMOTE_TEST_URL) and driven locally from the command line using;
+
+ $ ./remotetests.php -h
+
+
+--------------------------------------------------------------------------------
+ADDING TESTS
+
+The test cases are kept in the './cases' directory in a directory structure
+mirroring that of the Dokuwiki's
+
+Files with the extension .group.php are group tests (collections of
+one or more seperate unit test files) - there should be one group
+test per file in Dokuwiki's real directory.
+
+Individual tests files have the extension .test.php
+
+To add tests, create a .test.php file in the correct directory under ./cases
+Probably best to use one of the existing scripts as a basis
+
+The test will not be executable via one of the test runners (see above).
+
+To add it to a group of tests, modify the corresponding .group.php file.
+
+One exception to the naming convention - files named .webtest.php and
+.webgroup.php are run using SimpleTest's browser simulator.
+
diff --git a/_test/index.php b/_test/index.php
new file mode 100644
index 000000000..9b20cee39
--- /dev/null
+++ b/_test/index.php
@@ -0,0 +1,173 @@
+<?php
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+define('TEST_ROOT', dirname(__FILE__));
+define('TMPL_FILESCHEME_PATH', TEST_ROOT . '/filescheme/');
+error_reporting(E_ALL);
+
+set_time_limit(600);
+ini_set('memory_limit','128M');
+
+/* Used to determine output to display */
+define('DW_TESTS_OUTPUT_HTML',1);
+define('DW_TESTS_OUTPUT_XML',2);
+
+if ( isset($_GET['output']) && $_GET['output'] == 'xml' ) {
+ define('DW_TESTS_OUTPUT',DW_TESTS_OUTPUT_XML);
+} else {
+ define('DW_TESTS_OUTPUT',DW_TESTS_OUTPUT_HTML);
+}
+
+require_once 'lib/testmanager.php';
+TestManager::setup('tests.ini');
+
+if ( !defined('SIMPLE_TEST') ) {
+ define('SIMPLE_TEST', ConfigManager::getOptionAsPath('tests', 'simpletest', 'library_path'));
+}
+
+if (!@include_once SIMPLE_TEST . 'reporter.php') {
+ RaiseError('runtime', 'LIBRARY_REQUIRED', array(
+ 'library' => 'Simple Test',
+ 'path' => SIMPLE_TEST));
+}
+
+function & DW_TESTS_GetReporter() {
+ static $Reporter = NULL;
+ if ( !$Reporter ) {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ require_once SIMPLE_TEST . 'xml.php';
+ $Reporter = new XmlReporter();
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ $Reporter = new HTMLReporter();
+ break;
+ }
+ }
+ return $Reporter;
+}
+
+function DW_TESTS_PaintRunMore() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ echo "<p><a href='" . $_SERVER['PHP_SELF'] . "'>Run more tests</a></p>";
+ break;
+ }
+}
+
+function DW_TESTS_PaintHeader() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ header('Content-Type: text/xml; charset="utf-8"');
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ $header = <<<EOD
+<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'
+ 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
+<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
+ <head>
+ <meta http-equiv='Content-Type'
+ content='text/html; charset=iso-8859-1' />
+
+ <title>Dokuwiki: Unit Test Suite</title>
+ <link href="tests.css" type="text/css" rel="stylesheet" media="all"/>
+
+ </head>
+ <body>
+EOD;
+ echo $header;
+ default:
+ break;
+ }
+}
+
+function DW_TESTS_PaintSuiteHeader() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ echo "<h1>Dokuwiki: Unit Test Suite</h1>\n";
+ echo "<p><a href='index.php?show=groups'>Test groups</a>";
+ echo " || <a href='index.php?show=cases'>Test cases</a></p>";
+ break;
+ }
+}
+
+function DW_TESTS_PaintCaseList() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ echo XMLTestManager::getTestCaseList(TEST_CASES);
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ echo HTMLTestManager::getTestCaseList(TEST_CASES);
+ break;
+ }
+}
+
+function DW_TESTS_PaintGroupTestList() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ echo XMLTestManager::getGroupTestList(TEST_GROUPS);
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ echo HTMLTestManager::getGroupTestList(TEST_GROUPS);
+ break;
+ }
+}
+
+function DW_TESTS_PaintFooter() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ $footer = <<<EOD
+ </body>
+</html>
+EOD;
+ echo $footer;
+ break;
+ }
+}
+
+/** OUTPUT STARTS HERE **/
+
+// If it's a group test
+if (isset($_GET['group'])) {
+ if ('all' == $_GET['group']) {
+ TestManager::runAllTests(DW_TESTS_GetReporter());
+ } else {
+ TestManager::runGroupTest(ucfirst($_GET['group']),
+ TEST_GROUPS,
+ DW_TESTS_GetReporter());
+ }
+ DW_TESTS_PaintRunMore();
+ exit();
+}
+
+// If it's a single test case
+if (isset($_GET['case'])) {
+ TestManager::runTestCase($_GET['case'], TEST_CASES, DW_TESTS_GetReporter());
+ DW_TESTS_PaintRunMore();
+ exit();
+}
+
+// Else it's the main page
+DW_TESTS_PaintHeader();
+
+DW_TESTS_PaintSuiteHeader();
+
+if (isset($_GET['show']) && $_GET['show'] == 'cases') {
+ DW_TESTS_PaintCaseList();
+} else {
+ /* no group specified, so list them all */
+ DW_TESTS_PaintGroupTestList();
+}
+
+DW_TESTS_PaintFooter();
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);
+ }
+};
+
+}
diff --git a/_test/remotetests.php b/_test/remotetests.php
new file mode 100755
index 000000000..3dd290712
--- /dev/null
+++ b/_test/remotetests.php
@@ -0,0 +1,163 @@
+#!/usr/bin/php -q
+<?php
+ini_set('memory_limit','128M');
+
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+
+require_once 'lib/testmanager.php';
+TestManager::setup();
+
+function usage() {
+ $usage = <<<EOD
+Usage: ./remotetests.php [OPTION]...
+Run the Dokuwiki unit tests remotely executing tests over HTTP and delivering
+results to the command line. If ALL of the test cases pass a count of
+total passes is printed on STDOUT. If ANY of the test cases fail (or raise
+errors) details are printed on STDERR and this script returns a non-zero
+exit code.
+ -c --case=NAME specify a test case by it's ID (see -i for list)
+ -f --caseurl=NAME specify a test case file (full or relative path)
+ -g --group=NAME specify a grouptest. If no grouptest is
+ specified, all test cases will be run.
+ -i --caselist list individual test cases by their ID
+ -l --grouplist list available grouptests
+ -s, --separator=SEP set the character(s) used to separate fail
+ details to SEP
+ -p, --path path to SimpleTest installation
+ -h, --help display this help and exit
+ -u --url=TEST_URL specify remote server test url (w. index.php)
+
+EOD;
+ echo $usage;
+ exit(0);
+}
+
+/* default test options */
+$opt_separator = '->';
+$opt_caselist = FALSE;
+$opt_grouplist = FALSE;
+$opt_caseid = FALSE;
+$opt_caseurl = FALSE;
+$opt_groupfile = FALSE;
+$opt_url = FALSE;
+
+include_once(DOKU_INC.'inc/cliopts.php');
+$short_opts = "c:f:g:hils:p:u:";
+$long_opts = array("case=","caselist","help", "caseurl=", "group=", "grouplist", "separator=", "path=","url=");
+$OPTS = Doku_Cli_Opts::getOptions(__FILE__,$short_opts,$long_opts);
+if ( $OPTS->isError() ) {
+ fwrite( STDERR, $OPTS->getMessage() . "\n");
+ usage($available_grouptests);
+ exit(1);
+}
+
+foreach ($OPTS->options as $key => $val) {
+ switch ($key) {
+ case 'c':
+ case 'case':
+ $opt_caseid = $val;
+ break;
+ case 'h':
+ case 'help':
+ usage();
+ break;
+ case 'f':
+ case 'caseurl':
+ $opt_caseurl = $val;
+ break;
+ case 'g':
+ case 'group':
+ $opt_groupfile = $val;
+ break;
+ case 'i':
+ case 'caselist':
+ $opt_caselist = TRUE;
+ break;
+ case 'l':
+ case 'grouplist':
+ $opt_grouplist = TRUE;
+ break;
+ case 's':
+ case 'separator':
+ $opt_separator = $val;
+ break;
+ case 'p':
+ case 'path':
+ if (file_exists($val)) {
+ define('SIMPLE_TEST', $val);
+ }
+ break;
+ case 'u':
+ case '--url':
+ $opt_url = $val;
+ break;
+ }
+}
+
+if ( ! $opt_url ) {
+ if ( !defined('REMOTE_TEST_URL') ) {
+ fwrite( STDERR, "No test URL defined. Either modify tests.ini or use -u option\n");
+ exit(1);
+ } else {
+ $opt_url = REMOTE_TEST_URL;
+ }
+}
+
+
+if (!@include_once SIMPLE_TEST . 'reporter.php') {
+ if ( defined(SIMPLE_TEST) ) {
+ fwrite( STDERR, "Where's Simple Test ?!? Not at ".SIMPLE_TEST." \n");
+ } else {
+ fwrite( STDERR, "Where's Simple Test ?!? SIMPLE_TEST not even defined!\n");
+ }
+ exit(1);
+}
+
+require_once 'lib/cli_reporter.php';
+
+/* list grouptests */
+if ($opt_grouplist) {
+ $groups = RemoteTestManager::getGroupTestList($opt_url);
+ fwrite( STDOUT, "Available grouptests:\n");
+ foreach ( array_keys($groups) as $group ) {
+ fwrite( STDOUT, $group."\n");
+ }
+}
+
+/* list test cases */
+if ($opt_caselist) {
+ $cases = RemoteTestManager::getTestCaseList($opt_url);
+ fwrite( STDOUT, "Available tests tests:\n");
+ foreach ( array_keys($cases) as $case ) {
+ fwrite( STDOUT, $case."\n");
+ }
+}
+
+/* exit if we've displayed a list */
+if ( $opt_grouplist || $opt_caselist ) {
+ exit(0);
+}
+
+/* run a test case given it's URL */
+if ($opt_caseurl) {
+ RemoteTestManager::runTestUrl($opt_caseurl, new CLIReporter($opt_separator), $opt_url);
+ exit(0);
+}
+
+/* run a test case by id*/
+if ($opt_caseid) {
+ RemoteTestManager::runTestCase($opt_caseid, new CLIReporter($opt_separator), $opt_url);
+ exit(0);
+}
+
+/* run a grouptest */
+if ($opt_groupfile) {
+ RemoteTestManager::runGroupTest(
+ $opt_groupfile, new CLIReporter($opt_separator), $opt_url
+ );
+ exit(0);
+}
+/* run all tests */
+RemoteTestManager::runAllTests(new CLIReporter($opt_separator), $opt_url);
+exit(0);
+?> \ No newline at end of file
diff --git a/_test/rss2html.xsl b/_test/rss2html.xsl
new file mode 100644
index 000000000..ae56d2c20
--- /dev/null
+++ b/_test/rss2html.xsl
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+ @(#) $Id: rss2html.xsl,v 1.1 2004/06/11 22:00:57 harryf Exp $
+ -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rss="http://purl.org/rss/1.0/" xmlns="http://www.w3.org/1999/xhtml">
+
+<xsl:output method="html"/>
+
+<xsl:template match="/">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
+<style type="text/css">
+div.channel-title { font-family: sans-serif, arial, helvetica }
+</style>
+<style type="text/css">
+div.image { font-family: sans-serif, arial, helvetica }
+</style>
+<style type="text/css">
+div.image-description { font-family: sans-serif, arial, helvetica }
+</style>
+<style type="text/css">
+div.item-title { font-family: sans-serif, arial, helvetica }
+</style>
+<style type="text/css">
+div.item-description { font-family: sans-serif, arial, helvetica }
+</style>
+<style type="text/css">
+div.textinput-title { font-family: sans-serif, arial, helvetica }
+</style>
+<style type="text/css">
+div.textinput-form { font-family: sans-serif, arial, helvetica }
+</style>
+<title>
+<xsl:for-each select="rdf:RDF/rss:channel">
+<xsl:value-of select="rss:description"/>
+</xsl:for-each>
+</title>
+</head>
+<body>
+
+<xsl:for-each select="rdf:RDF/rss:image">
+<center><div class="image">
+<xsl:element name="a">
+ <xsl:attribute name="href"><xsl:value-of select="rss:link"/></xsl:attribute>
+ <xsl:element name="img">
+ <xsl:attribute name="src"><xsl:value-of select="rss:url"/></xsl:attribute>
+ <xsl:attribute name="alt"><xsl:value-of select="rss:title"/></xsl:attribute>
+ <xsl:attribute name="border">0</xsl:attribute>
+ </xsl:element>
+</xsl:element>
+</div></center>
+<center><div class="image-description">
+<xsl:value-of select="rss:description"/>
+</div></center>
+</xsl:for-each>
+
+<xsl:for-each select="rdf:RDF/rss:channel">
+<center><div class="channel-title">
+<xsl:element name="a">
+ <xsl:attribute name="href"><xsl:value-of select="rss:link"/></xsl:attribute>
+ <xsl:value-of select="rss:title"/>
+ <xsl:text> (</xsl:text>
+ <xsl:value-of select="dc:date"/>
+ <xsl:text>)</xsl:text>
+</xsl:element>
+</div></center>
+</xsl:for-each>
+
+<ul>
+<hr />
+<xsl:for-each select="rdf:RDF/rss:item">
+<div class="item-title"><li>
+<xsl:element name="a">
+ <xsl:attribute name="href"><xsl:value-of select="rss:link"/></xsl:attribute>
+ <xsl:value-of select="rss:title"/>
+</xsl:element>
+<xsl:text> (</xsl:text>
+<xsl:value-of select="dc:date"/>
+<xsl:text>)</xsl:text>
+</li></div>
+<div class="item-description"><xsl:value-of select="rss:description"/></div>
+<hr />
+</xsl:for-each>
+</ul>
+
+<xsl:for-each select="rdf:RDF/rss:textinput">
+<center><b><div class="textinput-title"><xsl:value-of select="rss:description"/></div></b></center>
+<xsl:element name="form">
+ <xsl:attribute name="action"><xsl:value-of select="rss:link"/></xsl:attribute>
+ <xsl:attribute name="method">POST</xsl:attribute>
+ <center><div class="textinput-form">
+ <xsl:element name="input">
+ <xsl:attribute name="name"><xsl:value-of select="rss:name"/></xsl:attribute>
+ <xsl:attribute name="type">text</xsl:attribute>
+ </xsl:element>
+ <xsl:text> </xsl:text>
+ <xsl:element name="input">
+ <xsl:attribute name="value"><xsl:value-of select="rss:title"/></xsl:attribute>
+ <xsl:attribute name="type">submit</xsl:attribute>
+ </xsl:element>
+</div></center>
+</xsl:element>
+</xsl:for-each>
+
+</body>
+</html>
+</xsl:template>
+
+</xsl:stylesheet> \ No newline at end of file
diff --git a/_test/runtests.php b/_test/runtests.php
new file mode 100755
index 000000000..ba9bc4b1d
--- /dev/null
+++ b/_test/runtests.php
@@ -0,0 +1,133 @@
+#!/usr/bin/php -q
+<?php
+ini_set('memory_limit','128M');
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+define('TEST_ROOT', dirname(__FILE__));
+define('TMPL_FILESCHEME_PATH', TEST_ROOT . '/filescheme/');
+error_reporting(E_ALL);
+
+require_once 'lib/testmanager.php';
+TestManager::setup();
+
+function usage() {
+ $usage = <<<EOD
+Usage: ./runtests.php [OPTION]...
+Run the Dokuwiki unit tests. If ALL of the test cases pass a count of total
+passes is printed on STDOUT. If ANY of the test cases fail (or raise
+errors) details are printed on STDERR and this script returns a non-zero
+exit code.
+ -c --case=NAME specify a test case by it's ID (see -i for list)
+ -f --file=NAME specify a test case file (full or relative path)
+ -g --group=NAME specify a grouptest. If no grouptest is
+ specified, all test cases will be run.
+ -i --caselist list individual test cases by their ID
+ -l --grouplist list available grouptests
+ -s, --separator=SEP set the character(s) used to separate fail
+ details to SEP
+ -p, --path path to SimpleTest installation
+ -h, --help display this help and exit
+
+EOD;
+ echo $usage;
+ exit(0);
+}
+
+/* test options */
+$opt_separator = '->';
+$opt_caselist = FALSE;
+$opt_grouplist = FALSE;
+$opt_caseid = FALSE;
+$opt_casefile = FALSE;
+$opt_groupfile = FALSE;
+
+include_once(DOKU_INC.'inc/cliopts.php');
+
+$short_opts = "c:f:g:hils:p:";
+$long_opts = array("case=","caselist","help", "file=", "group=", "grouplist", "separator=", "path=");
+$OPTS = Doku_Cli_Opts::getOptions(__FILE__,$short_opts,$long_opts);
+if ( $OPTS->isError() ) {
+ fwrite( STDERR, $OPTS->getMessage() . "\n");
+ usage($available_grouptests);
+ exit(1);
+}
+
+foreach ($OPTS->options as $key => $val) {
+ switch ($key) {
+ case 'c':
+ case 'case':
+ $opt_caseid = $val;
+ break;
+ case 'h':
+ case 'help':
+ usage();
+ break;
+ case 'f':
+ case 'file':
+ $opt_casefile = $val;
+ break;
+ case 'g':
+ case 'group':
+ $opt_groupfile = $val;
+ break;
+ case 'i':
+ case 'caselist':
+ $opt_caselist = TRUE;
+ break;
+ case 'l':
+ case 'grouplist':
+ $opt_grouplist = TRUE;
+ break;
+ case 's':
+ case 'separator':
+ $opt_separator = $val;
+ break;
+ case 'p':
+ case 'path':
+ if (file_exists($val)) {
+ define('SIMPLE_TEST', $val);
+ }
+ break;
+ }
+}
+
+if (!@include_once SIMPLE_TEST . 'reporter.php') {
+ die("Where's Simple Test ?!? Not at ".SIMPLE_TEST);
+}
+
+require_once 'lib/cli_reporter.php';
+
+/* list grouptests */
+if ($opt_grouplist) {
+ echo CLITestManager::getGroupTestList(TEST_GROUPS);
+}
+
+/* list test cases */
+if ($opt_caselist) {
+ echo CLITestManager::getTestCaseList(TEST_CASES);
+}
+
+/* exit if we've displayed a list */
+if ( $opt_grouplist || $opt_caselist ) {
+ exit(0);
+}
+
+/* run a test case */
+if ($opt_casefile) {
+ TestManager::runTestFile($opt_casefile, new CLIReporter($opt_separator));
+ exit(0);
+}
+/* run a test case by id*/
+if ($opt_caseid) {
+ TestManager::runTestCase($opt_caseid, TEST_CASES, new CLIReporter($opt_separator));
+ exit(0);
+}
+/* run a grouptest */
+if ($opt_groupfile) {
+ TestManager::runGroupTest($opt_groupfile, TEST_GROUPS,
+ new CLIReporter($opt_separator));
+ exit(0);
+}
+/* run all tests */
+TestManager::runAllTests(new CLIReporter($opt_separator));
+exit(0);
+?>
diff --git a/_test/tests.css b/_test/tests.css
new file mode 100644
index 000000000..c20d8bb4f
--- /dev/null
+++ b/_test/tests.css
@@ -0,0 +1,27 @@
+body {
+ background-color:#eee;
+ color:#000;
+ font:100%/1.2em Georgia,Verdana,Arial,Helvetica,sans-serif;
+ margin-left:20ex;
+ max-width:120ex;
+ }
+
+#sf { float:right; }
+
+h1 {
+ background-image:url(rephlux.png);
+ background-repeat:no-repeat;
+ margin-top:0;
+ padding:20px 0 0 90px;
+ color:#600;
+ font-size:3em;
+ line-height: 1em;
+ background-color:inherit;
+ border-bottom:9px double #333;
+ }
+
+pre {
+ font-size:120%;
+ line-height:1.2em;
+ color:#006;
+ } \ No newline at end of file
diff --git a/_test/tests.ini b/_test/tests.ini
new file mode 100644
index 000000000..cb16d4f1b
--- /dev/null
+++ b/_test/tests.ini
@@ -0,0 +1,12 @@
+TEST_ENABLED = 0
+
+; For performing "web tests" - PHP scripts acting as web browser
+WEB_TEST_URL = http://localhost/dokuwiki
+
+; See http://www.sitepoint.com/blogs/2004/06/15/simple-test-remote-testing/
+REMOTE_TEST_URL = http://localhost/dokuwiki/test/index.php
+
+;PROXY = http://proxyuser:proxypwd@proxy.yourdomain.com:8080
+
+; Path to Simple Test
+SIMPLE_TEST = ../../simpletest/
diff --git a/_test/webtest-stripper.sh b/_test/webtest-stripper.sh
new file mode 100755
index 000000000..f7991cc0b
--- /dev/null
+++ b/_test/webtest-stripper.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+################################################################################
+# Quick script to make simpletest web test fail output more legible
+#
+# Run the web test group from the command line w/ the command:
+#
+# $ ./runtests.php -g [GROUP] 2> tmp
+#
+# redirecting the error messages to the file tmp
+#
+# Then run this command on the tmp file
+#
+# $ ./webtest-stripper.sh tmp
+#
+################################################################################
+
+usage="Usage: ${0} [WEB_TEST_OUTPUT_FILE]";
+
+if [ -z "$1" ]; then
+ echo $usage;
+ exit 1;
+elif [ ! -f "$1" ]; then
+ echo "${1} is not a file!";
+ echo $usage;
+ exit 1;
+fi
+
+sed -e 's/\\n/\
+/g' "${1}" |\
+sed -e 's/\\//g' |\
+sed -e 's/FAIL.*Pattern \[\#\^/EXPECTED:\
+/g' |\
+sed -e 's/\$#i\].*string \[/\
+\
+GOT:\
+/g' |\
+sed -e 's/\]$/\
+----------------------------------------------------------------\
+/g'
+
+exit 0 \ No newline at end of file