-<?php
-//
-// PHP framework for testing, based on the design of "JUnit".
-//
-// Written by Fred Yankowski <fred@ontosys.com>
-// OntoSys, Inc <http://www.OntoSys.com>
-//
-// $Id: phpunit.php,v 1.1 2002/03/30 19:32:17 bmatzelle Exp $
-
-// Copyright (c) 2000 Fred Yankowski
-
-// Permission is hereby granted, free of charge, to any person
-// obtaining a copy of this software and associated documentation
-// files (the "Software"), to deal in the Software without
-// restriction, including without limitation the rights to use, copy,
-// modify, merge, publish, distribute, sublicense, and/or sell copies
-// of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-//
-error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE |
- E_CORE_ERROR | E_CORE_WARNING);
-
-/*
-interface Test {
- function run(&$aTestResult);
- function countTestCases();
-}
-*/
-
-function trace($msg) {
- return;
- print($msg);
- flush();
-}
-
-
-class Exception {
- /* Emulate a Java exception, sort of... */
- var $message;
- function Exception($message) {
- $this->message = $message;
- }
- function getMessage() {
- return $this->message;
- }
-}
-
-class Assert {
- function assert($boolean, $message=0) {
- if (! $boolean)
- $this->fail($message);
- }
-
- function assertEquals($expected, $actual, $message=0) {
- if ($expected != $actual) {
- $this->failNotEquals($expected, $actual, "expected", $message);
- }
- }
-
- function assertRegexp($regexp, $actual, $message=false) {
- if (! preg_match($regexp, $actual)) {
- $this->failNotEquals($regexp, $actual, "pattern", $message);
- }
- }
-
- function failNotEquals($expected, $actual, $expected_label, $message=0) {
- // Private function for reporting failure to match.
- $str = $message ? ($message . ' ') : "";
- $str .= "($expected_label/actual)<br>";
- $htmlExpected = htmlspecialchars($expected);
- $htmlActual = htmlspecialchars($actual);
- $str .= sprintf("<pre>%s\n--------\n%s</pre>",
- $htmlExpected, $htmlActual);
- $this->fail($str);
- }
-}
-
-class TestCase extends Assert /* implements Test */ {
- /* Defines context for running tests. Specific context -- such as
- instance variables, global variables, global state -- is defined
- by creating a subclass that specializes the setUp() and
- tearDown() methods. A specific test is defined by a subclass
- that specializes the runTest() method. */
- var $fName;
- var $fResult;
- var $fExceptions = array();
-
- function TestCase($name) {
- $this->fName = $name;
- }
-
- function run($testResult=0) {
- /* Run this single test, by calling the run() method of the
- TestResult object which will in turn call the runBare() method
- of this object. That complication allows the TestResult object
- to do various kinds of progress reporting as it invokes each
- test. Create/obtain a TestResult object if none was passed in.
- Note that if a TestResult object was passed in, it must be by
- reference. */
- if (! $testResult)
- $testResult = $this->_createResult();
- $this->fResult = $testResult;
- $testResult->run(&$this);
- $this->fResult = 0;
- return $testResult;
- }
-
- function countTestCases() {
- return 1;
- }
-
- function runTest() {
- $name = $this->name();
- // Since isset($this->$name) is false, no way to run defensive checks
- $this->$name();
- }
-
- function setUp() /* expect override */ {
- //print("TestCase::setUp()<br>\n");
- }
-
- function tearDown() /* possible override */ {
- //print("TestCase::tearDown()<br>\n");
- }
-
- ////////////////////////////////////////////////////////////////
-
-
- function _createResult() /* protected */ {
- /* override this to use specialized subclass of TestResult */
- return new TestResult;
- }
-
- function fail($message=0) {
- //printf("TestCase::fail(%s)<br>\n", ($message) ? $message : "");
- /* JUnit throws AssertionFailedError here. We just record the
- failure and carry on */
- $this->fExceptions[] = new Exception(&$message);
- }
-
- function error($message) {
- /* report error that requires correction in the test script
- itself, or (heaven forbid) in this testing infrastructure */
- printf('<b>ERROR: ' . $message . '</b><br>');
- $this->fResult->stop();
- }
-
- function failed() {
- return count($this->fExceptions);
- }
-
- function getExceptions() {
- return $this->fExceptions;
- }
-
- function name() {
- return $this->fName;
- }
-
- function runBare() {
- $this->setup();
- $this->runTest();
- $this->tearDown();
- }
-}
-
-
-class TestSuite /* implements Test */ {
- /* Compose a set of Tests (instances of TestCase or TestSuite), and
- run them all. */
- var $fTests = array();
-
- function TestSuite($classname=false) {
- if ($classname) {
- // Find all methods of the given class whose name starts with
- // "test" and add them to the test suite. We are just _barely_
- // able to do this with PHP's limited introspection... Note
- // that PHP seems to store method names in lower case, and we
- // have to avoid the constructor function for the TestCase class
- // superclass. This will fail when $classname starts with
- // "Test" since that will have a constructor method that will
- // get matched below and then treated (incorrectly) as a test
- // method. So don't name any TestCase subclasses as "Test..."!
- if (floor(phpversion()) >= 4) {
- // PHP4 introspection, submitted by Dylan Kuhn
- $names = get_class_methods($classname);
- while (list($key, $method) = each($names)) {
- if (preg_match('/^test/', $method) && $method != "testcase") {
- $this->addTest(new $classname($method));
- }
- }
- }
- else {
- $dummy = new $classname("dummy");
- $names = (array) $dummy;
- while (list($key, $value) = each($names)) {
- $type = gettype($value);
- if ($type == "user function" && preg_match('/^test/', $key)
- && $key != "testcase") {
- $this->addTest(new $classname($key));
- }
- }
- }
- }
- }
-
- function addTest($test) {
- /* Add TestCase or TestSuite to this TestSuite */
- $this->fTests[] = $test;
- }
-
- function run(&$testResult) {
- /* Run all TestCases and TestSuites comprising this TestSuite,
- accumulating results in the given TestResult object. */
- reset($this->fTests);
- while (list($na, $test) = each($this->fTests)) {
- if ($testResult->shouldStop())
- break;
- $test->run(&$testResult);
- }
- }
-
- function countTestCases() {
- /* Number of TestCases comprising this TestSuite (including those
- in any constituent TestSuites) */
- $count = 0;
- reset($fTests);
- while (list($na, $test_case) = each($this->fTests)) {
- $count += $test_case->countTestCases();
- }
- return $count;
- }
-}
-
-
-class TestFailure {
- /* Record failure of a single TestCase, associating it with the
- exception(s) that occurred */
- var $fFailedTestName;
- var $fExceptions;
-
- function TestFailure(&$test, &$exceptions) {
- $this->fFailedTestName = $test->name();
- $this->fExceptions = $exceptions;
- }
-
- function getExceptions() {
- return $this->fExceptions;
- }
- function getTestName() {
- return $this->fFailedTestName;
- }
-}
-
-
-class TestResult {
- /* Collect the results of running a set of TestCases. */
- var $fFailures = array();
- var $fRunTests = 0;
- var $fStop = false;
-
- function TestResult() { }
-
- function _endTest($test) /* protected */ {
- /* specialize this for end-of-test action, such as progress
- reports */
- }
-
- function getFailures() {
- return $this->fFailures;
- }
-
- function run($test) {
- /* Run a single TestCase in the context of this TestResult */
- $this->_startTest($test);
- $this->fRunTests++;
-
- $test->runBare();
-
- /* this is where JUnit would catch AssertionFailedError */
- $exceptions = $test->getExceptions();
- if ($exceptions)
- $this->fFailures[] = new TestFailure(&$test, &$exceptions);
- $this->_endTest($test);
- }
-
- function countTests() {
- return $this->fRunTests;
- }
-
- function shouldStop() {
- return $this->fStop;
- }
-
- function _startTest($test) /* protected */ {
- /* specialize this for start-of-test actions */
- }
-
- function stop() {
- /* set indication that the test sequence should halt */
- $fStop = true;
- }
-
- function countFailures() {
- return count($this->fFailures);
- }
-}
-
-
-class TextTestResult extends TestResult {
- /* Specialize TestResult to produce text/html report */
- function TextTestResult() {
- $this->TestResult(); // call superclass constructor
- }
-
- function report() {
- /* report result of test run */
- $nRun = $this->countTests();
- $nFailures = $this->countFailures();
- printf("<p>%s test%s run<br>", $nRun, ($nRun == 1) ? "" : 's');
- printf("%s failure%s.<br>\n", $nFailures, ($nFailures == 1) ? "" : 's');
- if ($nFailures == 0)
- return;
-
- print("<ol>\n");
- $failures = $this->getFailures();
- while (list($i, $failure) = each($failures)) {
- $failedTestName = $failure->getTestName();
- printf("<li>%s\n", $failedTestName);
-
- $exceptions = $failure->getExceptions();
- print("<ul>");
- while (list($na, $exception) = each($exceptions))
- printf("<li>%s\n", $exception->getMessage());
- print("</ul>");
- }
- print("</ol>\n");
- }
-
- function _startTest($test) {
- printf("%s ", $test->name());
- flush();
- }
-
- function _endTest($test) {
- $outcome = $test->failed()
- ? "<font color=\"red\">FAIL</font>"
- : "<font color=\"green\">ok</font>";
- printf("$outcome<br>\n");
- flush();
- }
-}
-
-
-class TestRunner {
- /* Run a suite of tests and report results. */
- function run($suite) {
- $result = new TextTestResult;
- $suite->run($result);
- $result->report();
- }
-}
-
-?>
+<?php\r
+//\r
+// PHP framework for testing, based on the design of "JUnit".\r
+//\r
+// Written by Fred Yankowski <fred@ontosys.com>\r
+// OntoSys, Inc <http://www.OntoSys.com>\r
+//\r
+// $Id: phpunit.php,v 1.1 2002/03/30 19:32:17 bmatzelle Exp $\r
+\r
+// Copyright (c) 2000 Fred Yankowski\r
+\r
+// Permission is hereby granted, free of charge, to any person\r
+// obtaining a copy of this software and associated documentation\r
+// files (the "Software"), to deal in the Software without\r
+// restriction, including without limitation the rights to use, copy,\r
+// modify, merge, publish, distribute, sublicense, and/or sell copies\r
+// of the Software, and to permit persons to whom the Software is\r
+// furnished to do so, subject to the following conditions:\r
+//\r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+//\r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+// SOFTWARE.\r
+//\r
+error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE |\r
+ E_CORE_ERROR | E_CORE_WARNING);\r
+\r
+/*\r
+interface Test {\r
+ function run(&$aTestResult);\r
+ function countTestCases();\r
+}\r
+*/\r
+\r
+function trace($msg) {\r
+ return;\r
+ print($msg);\r
+ flush();\r
+}\r
+\r
+\r
+class Exception {\r
+ /* Emulate a Java exception, sort of... */\r
+ var $message;\r
+ function Exception($message) {\r
+ $this->message = $message;\r
+ }\r
+ function getMessage() {\r
+ return $this->message;\r
+ }\r
+}\r
+\r
+class Assert {\r
+ function assert($boolean, $message=0) {\r
+ if (! $boolean)\r
+ $this->fail($message);\r
+ }\r
+\r
+ function assertEquals($expected, $actual, $message=0) {\r
+ if ($expected != $actual) {\r
+ $this->failNotEquals($expected, $actual, "expected", $message);\r
+ }\r
+ }\r
+\r
+ function assertRegexp($regexp, $actual, $message=false) {\r
+ if (! preg_match($regexp, $actual)) {\r
+ $this->failNotEquals($regexp, $actual, "pattern", $message);\r
+ }\r
+ }\r
+\r
+ function failNotEquals($expected, $actual, $expected_label, $message=0) {\r
+ // Private function for reporting failure to match.\r
+ $str = $message ? ($message . ' ') : '';\r
+ $str .= "($expected_label/actual)<br>";\r
+ $htmlExpected = htmlspecialchars($expected);\r
+ $htmlActual = htmlspecialchars($actual);\r
+ $str .= sprintf("<pre>%s\n--------\n%s</pre>",\r
+ $htmlExpected, $htmlActual);\r
+ $this->fail($str);\r
+ }\r
+}\r
+\r
+class TestCase extends Assert /* implements Test */ {\r
+ /* Defines context for running tests. Specific context -- such as\r
+ instance variables, global variables, global state -- is defined\r
+ by creating a subclass that specializes the setUp() and\r
+ tearDown() methods. A specific test is defined by a subclass\r
+ that specializes the runTest() method. */\r
+ var $fName;\r
+ var $fResult;\r
+ var $fExceptions = array();\r
+\r
+ function TestCase($name) {\r
+ $this->fName = $name;\r
+ }\r
+\r
+ function run($testResult=0) {\r
+ /* Run this single test, by calling the run() method of the\r
+ TestResult object which will in turn call the runBare() method\r
+ of this object. That complication allows the TestResult object\r
+ to do various kinds of progress reporting as it invokes each\r
+ test. Create/obtain a TestResult object if none was passed in.\r
+ Note that if a TestResult object was passed in, it must be by\r
+ reference. */\r
+ if (! $testResult)\r
+ $testResult = $this->_createResult();\r
+ $this->fResult = $testResult;\r
+ $testResult->run(&$this);\r
+ $this->fResult = 0;\r
+ return $testResult;\r
+ }\r
+\r
+ function countTestCases() {\r
+ return 1;\r
+ }\r
+\r
+ function runTest() {\r
+ $name = $this->name();\r
+ // Since isset($this->$name) is false, no way to run defensive checks\r
+ $this->$name();\r
+ }\r
+\r
+ function setUp() /* expect override */ {\r
+ //print("TestCase::setUp()<br>\n");\r
+ }\r
+\r
+ function tearDown() /* possible override */ {\r
+ //print("TestCase::tearDown()<br>\n");\r
+ }\r
+\r
+ ////////////////////////////////////////////////////////////////\r
+\r
+\r
+ function _createResult() /* protected */ {\r
+ /* override this to use specialized subclass of TestResult */\r
+ return new TestResult;\r
+ }\r
+\r
+ function fail($message=0) {\r
+ //printf("TestCase::fail(%s)<br>\n", ($message) ? $message : '');\r
+ /* JUnit throws AssertionFailedError here. We just record the\r
+ failure and carry on */\r
+ $this->fExceptions[] = new Exception(&$message);\r
+ }\r
+\r
+ function error($message) {\r
+ /* report error that requires correction in the test script\r
+ itself, or (heaven forbid) in this testing infrastructure */\r
+ printf('<b>ERROR: ' . $message . '</b><br>');\r
+ $this->fResult->stop();\r
+ }\r
+\r
+ function failed() {\r
+ return count($this->fExceptions);\r
+ }\r
+\r
+ function getExceptions() {\r
+ return $this->fExceptions;\r
+ }\r
+\r
+ function name() {\r
+ return $this->fName;\r
+ }\r
+\r
+ function runBare() {\r
+ $this->setup();\r
+ $this->runTest();\r
+ $this->tearDown();\r
+ }\r
+}\r
+\r
+\r
+class TestSuite /* implements Test */ {\r
+ /* Compose a set of Tests (instances of TestCase or TestSuite), and\r
+ run them all. */\r
+ var $fTests = array();\r
+\r
+ function TestSuite($classname=false) {\r
+ if ($classname) {\r
+ // Find all methods of the given class whose name starts with\r
+ // "test" and add them to the test suite. We are just _barely_\r
+ // able to do this with PHP's limited introspection... Note\r
+ // that PHP seems to store method names in lower case, and we\r
+ // have to avoid the constructor function for the TestCase class\r
+ // superclass. This will fail when $classname starts with\r
+ // "Test" since that will have a constructor method that will\r
+ // get matched below and then treated (incorrectly) as a test\r
+ // method. So don't name any TestCase subclasses as "Test..."!\r
+ if (floor(phpversion()) >= 4) {\r
+ // PHP4 introspection, submitted by Dylan Kuhn\r
+ $names = get_class_methods($classname);\r
+ while (list($key, $method) = each($names)) {\r
+ if (preg_match('/^test/', $method) && $method != "testcase") { \r
+ $this->addTest(new $classname($method));\r
+ }\r
+ }\r
+ }\r
+ else {\r
+ $dummy = new $classname("dummy");\r
+ $names = (array) $dummy;\r
+ while (list($key, $value) = each($names)) {\r
+ $type = gettype($value);\r
+ if ($type == "user function" && preg_match('/^test/', $key)\r
+ && $key != "testcase") { \r
+ $this->addTest(new $classname($key));\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ function addTest($test) {\r
+ /* Add TestCase or TestSuite to this TestSuite */\r
+ $this->fTests[] = $test;\r
+ }\r
+\r
+ function run(&$testResult) {\r
+ /* Run all TestCases and TestSuites comprising this TestSuite,\r
+ accumulating results in the given TestResult object. */\r
+ reset($this->fTests);\r
+ while (list($na, $test) = each($this->fTests)) {\r
+ if ($testResult->shouldStop())\r
+ break;\r
+ $test->run(&$testResult);\r
+ }\r
+ }\r
+\r
+ function countTestCases() {\r
+ /* Number of TestCases comprising this TestSuite (including those\r
+ in any constituent TestSuites) */\r
+ $count = 0;\r
+ reset($fTests);\r
+ while (list($na, $test_case) = each($this->fTests)) {\r
+ $count += $test_case->countTestCases();\r
+ }\r
+ return $count;\r
+ }\r
+}\r
+\r
+\r
+class TestFailure {\r
+ /* Record failure of a single TestCase, associating it with the\r
+ exception(s) that occurred */\r
+ var $fFailedTestName;\r
+ var $fExceptions;\r
+\r
+ function TestFailure(&$test, &$exceptions) {\r
+ $this->fFailedTestName = $test->name();\r
+ $this->fExceptions = $exceptions;\r
+ }\r
+\r
+ function getExceptions() {\r
+ return $this->fExceptions;\r
+ }\r
+ function getTestName() {\r
+ return $this->fFailedTestName;\r
+ }\r
+}\r
+\r
+\r
+class TestResult {\r
+ /* Collect the results of running a set of TestCases. */\r
+ var $fFailures = array();\r
+ var $fRunTests = 0;\r
+ var $fStop = false;\r
+\r
+ function TestResult() { }\r
+\r
+ function _endTest($test) /* protected */ {\r
+ /* specialize this for end-of-test action, such as progress\r
+ reports */\r
+ }\r
+\r
+ function getFailures() {\r
+ return $this->fFailures;\r
+ }\r
+\r
+ function run($test) {\r
+ /* Run a single TestCase in the context of this TestResult */\r
+ $this->_startTest($test);\r
+ $this->fRunTests++;\r
+\r
+ $test->runBare();\r
+\r
+ /* this is where JUnit would catch AssertionFailedError */\r
+ $exceptions = $test->getExceptions();\r
+ if ($exceptions)\r
+ $this->fFailures[] = new TestFailure(&$test, &$exceptions);\r
+ $this->_endTest($test);\r
+ }\r
+\r
+ function countTests() {\r
+ return $this->fRunTests;\r
+ }\r
+\r
+ function shouldStop() {\r
+ return $this->fStop;\r
+ }\r
+\r
+ function _startTest($test) /* protected */ {\r
+ /* specialize this for start-of-test actions */\r
+ }\r
+\r
+ function stop() {\r
+ /* set indication that the test sequence should halt */\r
+ $fStop = true;\r
+ }\r
+\r
+ function countFailures() {\r
+ return count($this->fFailures);\r
+ }\r
+}\r
+\r
+\r
+class TextTestResult extends TestResult {\r
+ /* Specialize TestResult to produce text/html report */\r
+ function TextTestResult() {\r
+ $this->TestResult(); // call superclass constructor\r
+ }\r
+ \r
+ function report() {\r
+ /* report result of test run */\r
+ $nRun = $this->countTests();\r
+ $nFailures = $this->countFailures();\r
+ printf("<p>%s test%s run<br>", $nRun, ($nRun == 1) ? '' : 's');\r
+ printf("%s failure%s.<br>\n", $nFailures, ($nFailures == 1) ? '' : 's');\r
+ if ($nFailures == 0)\r
+ return;\r
+\r
+ print("<ol>\n");\r
+ $failures = $this->getFailures();\r
+ while (list($i, $failure) = each($failures)) {\r
+ $failedTestName = $failure->getTestName();\r
+ printf("<li>%s\n", $failedTestName);\r
+\r
+ $exceptions = $failure->getExceptions();\r
+ print("<ul>");\r
+ while (list($na, $exception) = each($exceptions))\r
+ printf("<li>%s\n", $exception->getMessage());\r
+ print("</ul>");\r
+ }\r
+ print("</ol>\n");\r
+ }\r
+\r
+ function _startTest($test) {\r
+ printf("%s ", $test->name());\r
+ flush();\r
+ }\r
+\r
+ function _endTest($test) {\r
+ $outcome = $test->failed()\r
+ ? "<font color=\"red\">FAIL</font>"\r
+ : "<font color=\"green\">ok</font>";\r
+ printf("$outcome<br>\n");\r
+ flush();\r
+ }\r
+}\r
+\r
+\r
+class TestRunner {\r
+ /* Run a suite of tests and report results. */\r
+ function run($suite) {\r
+ $result = new TextTestResult;\r
+ $suite->run($result);\r
+ $result->report();\r
+ }\r
+}\r
+\r
+?>\r