From 08d7babffe1bded4620d0a3624bdd80522283138 Mon Sep 17 00:00:00 2001
From: Michael Klier <chi@chimeric.de>
Date: Tue, 30 Mar 2010 11:15:08 +0200
Subject: [PATCH] added support for plugin unittests

	This patch adds support to include plugin tests in the
	DokuWiki testsuite. Plugin tests are located in a dedicated
	directory _test/within a plugin directory. The naming
	convention of the test files follows the one used in
	DokuWikis testsuite.

		<plugin>/_test/*.test.php 	-> single test
		<plugin>/_test/*.group.php  -> group test

	The plugin tests are accessible via the web interface
	of the test suite and via the cli interface. It is recommend
	to bundle plugin test in a plugin group test. The webinterface
	also allows to run all plugin tests at once.

	Test files must include:

		<dokuwiki>/_test/lib/unittest.php

	Example Test:

	require_once(DOKU_INC.'_test/lib/unittest.php');
	class plugin_test extends Doku_UnitTestCase {
		function test() {
			$this->assertEqual(1,1);
		}
	}

	Example Group Test:

	require_once(DOKU_INC.'_test/lib/unittest.php');
	class plugin_group_test extends Doku_GroupTest {
		function group_test() {
			$dir = dirname(__FILE__).'/';
			$this->GroupTest('plugin_grouptest');
			$this->addTestFile($dir . 'plugin.test1.php');
			$this->addTestFile($dir . 'plugin.test2.php');
			$this->addTestFile($dir . 'plugin.test3.php');
		}
	}

	At the moment unittest.php contains only two
	meta classes so plugins tests don't have to inherit
	from the simpletest classes.

	This patch should be treated as intermediate step to
	allow for plugin tests. The testsuite wasn't designed
	to include plugin tests. It should probably be refactored
	at a later point.
---
 _test/index.php           | 46 ++++++++++++++++++++
 _test/lib/testmanager.php | 91 ++++++++++++++++++++++++++++++++++++---
 _test/lib/unittest.php    |  5 +++
 _test/runtests.php        | 56 ++++++++++++++++++++++--
 4 files changed, 190 insertions(+), 8 deletions(-)
 create mode 100644 _test/lib/unittest.php

diff --git a/_test/index.php b/_test/index.php
index 87cc10a35..f59c44cf4 100644
--- a/_test/index.php
+++ b/_test/index.php
@@ -130,6 +130,30 @@ function DW_TESTS_PaintGroupTestList() {
     }
 }
 
+function DW_TESTS_PaintPluginTestCaseList() {
+    switch ( DW_TESTS_OUTPUT ) {
+        case DW_TESTS_OUTPUT_XML:
+            echo XMLTestManager::getPluginTestCaseList(TEST_PLUGINS);
+        break;
+        case DW_TESTS_OUTPUT_HTML:
+        default:
+            echo HTMLTestManager::getPluginTestCaseList(TEST_PLUGINS);
+        break;
+    }
+}
+
+function DW_TESTS_PaintPluginGroupTestList() {
+    switch ( DW_TESTS_OUTPUT ) {
+        case DW_TESTS_OUTPUT_XML:
+            echo XMLTestManager::getPluginGroupTestList(TEST_PLUGINS);
+        break;
+        case DW_TESTS_OUTPUT_HTML:
+        default:
+            echo HTMLTestManager::getPluginGroupTestList(TEST_PLUGINS);
+        break;
+    }
+}
+
 function DW_TESTS_PaintFooter() {
     switch ( DW_TESTS_OUTPUT ) {
         case DW_TESTS_OUTPUT_XML:
@@ -160,6 +184,19 @@ if (isset($_GET['group'])) {
     exit();
 }
 
+// If it's a plugin group test
+if (isset($_GET['plugin_group'])) {
+    if ('all' == $_GET['plugin_group']) {
+        TestManager::runAllPluginTests(DW_TESTS_GetReporter());
+    } else {
+        TestManager::runGroupTest(ucfirst($_GET['plugin_group']),
+                                  TEST_PLUGINS,
+                                  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());
@@ -167,6 +204,13 @@ if (isset($_GET['case'])) {
     exit();
 }
 
+// If it's a single plugin test case
+if (isset($_GET['plugin_case'])) {
+    TestManager::runTestCase($_GET['plugin_case'], TEST_PLUGINS, DW_TESTS_GetReporter());
+    DW_TESTS_PaintRunMore();
+    exit();
+}
+
 // Else it's the main page
 DW_TESTS_PaintHeader();
 
@@ -174,9 +218,11 @@ DW_TESTS_PaintSuiteHeader();
 
 if (isset($_GET['show']) && $_GET['show'] == 'cases') {
     DW_TESTS_PaintCaseList();
+    DW_TESTS_PaintPluginTestCaseList();
 } else {
     /* no group specified, so list them all */
     DW_TESTS_PaintGroupTestList();
+    DW_TESTS_PaintPluginGroupTestList();
 }
 
 DW_TESTS_PaintFooter();
diff --git a/_test/lib/testmanager.php b/_test/lib/testmanager.php
index 14cc20bf3..96c9a57a2 100644
--- a/_test/lib/testmanager.php
+++ b/_test/lib/testmanager.php
@@ -5,6 +5,7 @@
 
 define('TEST_GROUPS',realpath(dirname(__FILE__).'/../cases'));
 define('TEST_CASES',realpath(dirname(__FILE__).'/../cases'));
+define('TEST_PLUGINS',realpath(dirname(__FILE__).'/../../lib/plugins'));
 
 // try to load runkit extension
 if (!extension_loaded('runkit') && function_exists('dl')) {
@@ -59,6 +60,17 @@ class TestManager {
         $test->run($reporter);
     }
 
+    function runAllPluginTests(&$reporter) {
+        $manager =& new TestManager();
+        $test_cases =& $manager->_getTestFileList(TEST_PLUGINS);
+        $test =& new GroupTest('All Plugin 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();
         
@@ -125,12 +137,12 @@ class TestManager {
     }
 
     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(TEST_GROUPS . DIRECTORY_SEPARATOR, '', $case);
+            $case = str_replace(TEST_PLUGINS . DIRECTORY_SEPARATOR, '', $case);
             $case = str_replace(DIRECTORY_SEPARATOR, ':', $case);
             $testcases[$testcase_file] = $case;
         }
@@ -142,6 +154,16 @@ class TestManager {
                                             array(&$this, '_isTestCaseFile'));
     }
 
+    function &getPluginTestCaseList($directory = '.') {
+        $manager =& new TestManager();
+        return $manager->_getTestCaseList($directory);
+    }
+
+    function &getPluginGroupTestList($directory = '.') {
+        $manager =& new TestManager();
+        return $manager->_getTestGroupList($directory);
+    }
+
     function &getGroupTestList($directory = '.') {
         $manager =& new TestManager();
         return $manager->_getTestGroupList($directory);
@@ -153,12 +175,12 @@ class TestManager {
     }
 
     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(TEST_GROUPS . DIRECTORY_SEPARATOR, '', $group);
+            $group = str_replace(TEST_PLUGINS . DIRECTORY_SEPARATOR, '', $group);
             $group = str_replace(DIRECTORY_SEPARATOR, ':', $group);
             $grouptests[$grouptest_file] = $group;
         }
@@ -168,7 +190,7 @@ class TestManager {
 
     function &_getGroupTestClassNames($grouptest_file) {
         $file = implode("\n", file($grouptest_file));
-        preg_match("~lass\s+?(.*)\s+?extends GroupTest~", $file, $matches);
+        preg_match("~lass\s+?(.*)\s+?extends .*?GroupTest~", $file, $matches);
         if (! empty($matches)) {
             unset($matches[0]);
             return $matches;
@@ -242,6 +264,29 @@ class CLITestManager extends TestManager {
         }
         return $buffer . "\n";
     }
+
+    function &getPluginTestCaseList($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";
+    }
+
+    function &getPluginGroupTestList($directory = '.') {
+        $manager =& new CLITestManager();
+        $test_cases =& $manager->_getTestGroupList($directory);
+
+        $buffer = "Available test cases:\n";
+        foreach ($test_cases as $test_case) {
+            $buffer .= "  " . $test_case . "\n";
+        }
+        return $buffer . "\n";
+    }
+
 }
 
 class HTMLTestManager extends TestManager {
@@ -289,6 +334,42 @@ class HTMLTestManager extends TestManager {
         $buffer .= "</ul>\n";
         return $buffer;
     }
+
+    function &getPluginTestCaseList($directory = '.') {
+        $manager =& new HTMLTestManager();
+        $testcases =& $manager->_getTestCaseList($directory);
+
+        if (1 > count($testcases)) {
+            return "<p>No plugin test cases set up!</p>";
+        }
+        $buffer = "<p>Available plugin test cases:</p>\n<ul>";
+        foreach ($testcases as $testcase) {
+            $buffer .= "<li><a href='" . $manager->getBaseURL() .
+                "?plugin_case=" . urlencode($testcase) . "'>" .
+                $testcase . "</a></li>\n";
+        }
+
+        $buffer .= "</ul>\n";
+        return $buffer;
+    }
+
+    function &getPluginGroupTestList($directory = '.') {
+        $manager =& new HTMLTestManager();
+        $group_tests =& $manager->_getTestGroupList($directory);
+        if (1 > count($group_tests)) {
+            return "<p>No plugin test groups set up!</p>";
+        }
+        $buffer = "<p>Available plugin groups:</p>\n<ul>";
+        $buffer .= "<li><a href='" . $manager->getBaseURL() . "?plugin_group=all'>All tests</a></li>\n";
+        foreach ($group_tests as $group_test) {
+            $buffer .= "<li><a href='" . $manager->getBaseURL() . "?plugin_group={$group_test}'>" .
+                $group_test . "</a></li>\n";
+        }
+
+        $buffer .= "</ul>\n";
+        return $buffer;
+    }
+
 }
 
 /**
diff --git a/_test/lib/unittest.php b/_test/lib/unittest.php
new file mode 100644
index 000000000..220aa6c1b
--- /dev/null
+++ b/_test/lib/unittest.php
@@ -0,0 +1,5 @@
+<?php
+class Doku_UnitTestCase extends UnitTestCase {
+}
+class Doku_GroupTest extends GroupTest {
+}
diff --git a/_test/runtests.php b/_test/runtests.php
index e122c59fb..8b93efec3 100755
--- a/_test/runtests.php
+++ b/_test/runtests.php
@@ -21,11 +21,17 @@ 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)
+  --pcase=NAME            specify a plugin test case by it's ID 
+                          (see --plugincaselist 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.
+  --pgroup=NAME           specify a plugin 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
+  --plugincaselist        list all individual plugin test cases by their ID
+  --plugingrouplist       list avialable plugin grouptests
   -s, --separator=SEP     set the character(s) used to separate fail
                           details to SEP
   -p, --path              path to SimpleTest installation
@@ -40,14 +46,18 @@ EOD;
 $opt_separator = '->';
 $opt_caselist = FALSE;
 $opt_grouplist = FALSE;
+$opt_plugincaselist = FALSE;
+$opt_plugingrouplist = FALSE;
 $opt_caseid = FALSE;
+$top_plugincaseid = FALSE;
 $opt_casefile = FALSE;
 $opt_groupfile = FALSE;
+$opt_plugingroupfile = 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=");
+$long_opts  = array("case=","pcase=","caselist","help", "file=", "group=", "pgroup=", "grouplist", "plugincaselist", "plugingrouplist", "separator=", "path=");
 $OPTS = Doku_Cli_Opts::getOptions(__FILE__,$short_opts,$long_opts);
 if ( $OPTS->isError() ) {
     fwrite( STDERR, $OPTS->getMessage() . "\n");
@@ -61,6 +71,9 @@ foreach ($OPTS->options as $key => $val) {
         case 'case':
             $opt_caseid = $val;
             break;
+        case 'pcase':
+            $opt_plugincaseid = $val;
+            break;
         case 'h':
         case 'help':
             usage();
@@ -73,6 +86,9 @@ foreach ($OPTS->options as $key => $val) {
         case 'group':
             $opt_groupfile = $val;
             break;
+        case 'pgroup':
+            $opt_plugingroupfile = $val;
+            break;
         case 'i':
         case 'caselist':
             $opt_caselist = TRUE;
@@ -81,6 +97,12 @@ foreach ($OPTS->options as $key => $val) {
         case 'grouplist':
             $opt_grouplist = TRUE;
             break;
+        case 'plugincaselist':
+            $opt_plugincaselist = TRUE;
+            break;
+        case 'plugingrouplist':
+            $opt_plugingrouplist = TRUE;
+            break;
         case 's':
         case 'separator':
             $opt_separator = $val;
@@ -110,8 +132,18 @@ if ($opt_caselist) {
     echo CLITestManager::getTestCaseList(TEST_CASES);
 }
 
+/* list plugin test cases */
+if ($opt_plugincaselist) {
+    echo CLITestManager::getPluginTestCaseList(TEST_PLUGINS);
+}
+
+/* list plugin group tests */
+if($opt_plugingrouplist) {
+    echo CLITestManager::getPluginGroupTestList(TEST_PLUGINS);
+}
+
 /* exit if we've displayed a list */
-if ( $opt_grouplist || $opt_caselist ) {
+if ( $opt_grouplist || $opt_caselist || $opt_plugincaselist || $opt_plugingrouplist ) {
     exit(0);
 }
 
@@ -120,17 +152,35 @@ if ($opt_casefile) {
     TestManager::runTestFile($opt_casefile, new CLIReporter($opt_separator));
     exit(0);
 }
-/* run a test case by id*/
+
+/* run a test case by id */
 if ($opt_caseid) {
     TestManager::runTestCase($opt_caseid, TEST_CASES, new CLIReporter($opt_separator));
     exit(0);
 }
+
+/* run a plugin test by case id */
+if ($opt_plugincaseid) {
+    TestManager::runTestCase($opt_plugincaseid, TEST_PLUGINS, 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 a plugin grouptest */
+if ($opt_plugingroupfile) {
+    TestManager::runGroupTest($opt_plugingroupfile, TEST_PLUGINS,
+                              new CLIReporter($opt_separator));
+    exit(0);
+}
+
+/* run a plugin group test */
+//FIXME
 /* run all tests */
 TestManager::runAllTests(new CLIReporter($opt_separator));
 exit(0);
-- 
GitLab