]> git.mxchange.org Git - mailer.git/blobdiff - inc/phpmailer/test/phpunit.php
Re-added
[mailer.git] / inc / phpmailer / test / phpunit.php
diff --git a/inc/phpmailer/test/phpunit.php b/inc/phpmailer/test/phpunit.php
new file mode 100644 (file)
index 0000000..3344769
--- /dev/null
@@ -0,0 +1,376 @@
+<?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();
+  }
+}
+
+?>