//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// *WITHOUT ANY WARRANTY*; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. If not, see .
// Topic: Description
//
// Useful for invoking series of small tests, probably from a Makefile. The
// testing section of this library's Makefile follows. Note that we're using
// "find" rather than iterate with PHP's opendir() to make sure that a fatal
// error in one test file does not affect any other files. This prevents us
// from knowing the length of the longest file for display alignment, but I
// prefer function over form in this case.
//
// (begin example)
// test: dep
// @find t -name '*.php' -exec php -d include_path=lib -f '{}' ';'
// @echo "*** See 'test.log' for details."
// (end example)
//
// The above iterates through each ".php" file in directory "t/" and any
// subdirectory therein, displays a summary of results on screen and saves
// full debugging output in "test.log".
//
// Example test file:
//
// (begin example)
// require_once 'Test.inc';
//
// ok(function_exists('a_function_of_yours'), true); # This is test 1
//
// okDiff('foobar', a_function_of_yours('raboof')); # This is test 2
// (end example)
// Private Class: Test
//
class Test {
// Private Constructor: __construct
//
function __construct() {
$this->goods = 0;
$this->total = 0;
$this->faileds = Array();
$this->log = fopen("test.log","a");
ob_implicit_flush(false);
ob_start();
}
// Private Destructor: __destruct
//
function __destruct() {
ob_end_clean();
if ($this->goods >= $this->total) echo " ok";
else echo " FAILED\n\tFailed test numbers: " . join(',', $this->faileds);
echo "\n";
if ($this->log) fclose($this->log); // I like things nice and explicit.
}
// Private Method: _ok
//
// See .
function ok($bool, $fatal = false) {
$this->total++;
$out = ob_get_contents();
ob_end_clean(); // PHP has a bug, cannot use ob_get_clean() in CLI mode; closes the OB!
if ($bool) {
$this->goods++;
if ($this->log) fwrite($this->log, "*** {$_SERVER['PHP_SELF']} TEST {$this->total} OK\n");
} else {
$this->faileds[] = $this->total;
if ($this->log) fwrite($this->log, "*** {$_SERVER['PHP_SELF']} TEST {$this->total} FAILED. OUTPUT:\n\n{$out}\n\n");
};
echo sprintf("\r%-50s %3s / %3s", $_SERVER['PHP_SELF'], $this->goods, $this->total);
ob_start(); // Restart OB to complete PHP bug workaround. Makes progress output easier anyway.
// Bail out of everything if we failed a fatal-type test.
if (!$bool && $fatal) {
// PHP 5 is nice and will still call __destruct(). Better in fact
// than if I tried to do so explicitly here.
exit(0);
};
}
}
// Necessary to simulate atexit() with class destructor.
$globalTestInstance = new Test();
// Convenient syntax inspired by Perl's Test.pm.
// Function: ok
//
// Log a test result. If a second argument is true, this will be the last
// test performed in this file if it fails.
function ok($bool, $fatal = false) {
global $globalTestInstance;
$globalTestInstance->ok($bool, $fatal);
};
// Function: okDiff
//
// Wrapper around and . Will display any difference
// between arguments 1 and 2 and consider the test a success if they match
// *perfectly*. A match means that both not only represent the same value,
// but are also of the same type. (i.e. "2", 2 and 2.0 are three different
// things.) If the arguments are arrays, they are compared properly whether
// they are hashes or indexed, in both directions with full recursion to find
// any possible differences, thanks to .
//
// As with , a if a third argument is true, this will be the last test
// performed in this file if it fails.
function okDiff($left, $right, $fatal = false) {
require_once('array_compare.inc');
var_dump($diff = array_compare($left, $right));
ok($diff === false);
};
?>