console entry point stuff

This commit is contained in:
tmont 2009-06-13 08:15:05 +00:00
parent 0fb4d1e9a2
commit c44ccb62b3
9 changed files with 482 additions and 37 deletions

View File

@ -2,7 +2,7 @@
require_once 'util/Autoloader.php';
Autoloader::loadClassMap(dirname(__FILE__) . '/manifest.php');
Autoloader::loadClassMapFromFile(dirname(__FILE__) . '/manifest.php');
spl_autoload_register('Autoloader::autoload');
?>

View File

@ -1,6 +1,6 @@
<?php
class CombinedCaseResult implements TestResult {
class CombinedTestResult implements TestResult {
protected $testResults;

View File

@ -2,14 +2,12 @@
class TestListener {
protected $reporter;
public function __construct(TestReporter $reporter) {
$this->reporter = $reporter;
public function __construct() {
}
public function beforeTestSuite(TestSuite $suite) {
}
public function afterTestSuite(TestSuite $suite) {
@ -32,31 +30,27 @@
}
public function onTestCaseErred(TestCase $test) {
public function beforeTestMethod(TestMethod $method) {
}
public function beforeTestMethod(ReflectionMethod $method) {
public function afterTestMethod(TestMethod $method) {
}
public function afterTestMethod(ReflectionMethod $method) {
public function onTestMethodFailed(TestMethod $method) {
}
public function onTestMethodFailed(ReflectionMethod $method) {
public function onTestMethodPassed(TestMethod $method) {
}
public function onTestMethodPassed(ReflectionMethod $method) {
public function onTestMethodErred(TestMethod $method) {
}
public function onTestMethodErred(ReflectionMethod $method) {
}
public function onTestMethodIgnored(ReflectionMethod $method) {
public function onTestMethodIgnored(TestMethod $method) {
}

View File

@ -5,7 +5,7 @@
protected $name;
protected $tests;
public function __construct($name, array $tests) {
public function __construct($name, array $tests = array()) {
$this->name = $name;
$this->tests = $tests;
}

View File

@ -0,0 +1,179 @@
<?php
class ConsoleListener {
private $verbosity;
const VERBOSITY_LOW = 0;
const VERBOSITY_MEDIUM = 1;
const VERBOSITY_HIGH = 2;
public function __construct($verbosity = self::VERBOSITY_MEDIUM) {
$this->verbosity = intval($verbosity);
}
private function out($text) {
fwrite(STDOUT, $text);
}
private function err($text) {
fwrite(STDERR, $text);
}
public function beforeTestSuite(TestSuite $suite) {
switch ($this->verbosity) {
case self::VERBOSITY_HIGH:
$this->out("\n" . $suite->getName() . "\n");
break;
case self::VERBOSITY_LOW:
case self::VERBOSITY_MEDIUM:
default:
break;
}
}
public function afterTestSuite(TestSuite $suite) {
switch ($this->verbosity) {
case self::VERBOSITY_HIGH:
$this->out("\n");
break;
case self::VERBOSITY_LOW:
case self::VERBOSITY_MEDIUM:
default:
break;
}
}
public function beforeTestCase(TestCase $test) {
switch ($this->verbosity) {
case self::VERBOSITY_HIGH:
$this->out(' ' . $test->getName() . "\n");
break;
case self::VERBOSITY_LOW:
case self::VERBOSITY_MEDIUM:
default:
break;
}
}
public function afterTestCase(TestCase $test) {
switch ($this->verbosity) {
case self::VERBOSITY_HIGH:
$this->out("\n");
break;
case self::VERBOSITY_LOW:
case self::VERBOSITY_MEDIUM:
default:
break;
}
}
public function onTestCaseFailed(TestCase $test) {
switch ($this->verbosity) {
case self::VERBOSITY_HIGH:
$this->out(" !!TEST CASE FAILED!!\n");
break;
case self::VERBOSITY_LOW:
case self::VERBOSITY_MEDIUM:
default:
break;
}
}
public function onTestCasePassed(TestCase $test) {
switch ($this->verbosity) {
case self::VERBOSITY_HIGH:
$this->out(" test case passed\n");
break;
case self::VERBOSITY_LOW:
case self::VERBOSITY_MEDIUM:
default:
break;
}
}
public function beforeTestMethod(TestMethod $method) {
switch ($this->verbosity) {
case self::VERBOSITY_HIGH:
$this->out(' ' . $method->getName() . "\n");
break;
case self::VERBOSITY_LOW:
case self::VERBOSITY_MEDIUM:
default:
break;
}
}
public function afterTestMethod(TestMethod $method) {
switch ($this->verbosity) {
case self::VERBOSITY_HIGH:
$this->out("\n");
break;
case self::VERBOSITY_LOW:
case self::VERBOSITY_MEDIUM:
default:
break;
}
}
public function onTestMethodFailed(TestMethod $method) {
switch ($this->verbosity) {
case self::VERBOSITY_LOW:
break;
case self::VERBOSITY_HIGH:
case self::VERBOSITY_MEDIUM:
default:
$this->out('F');
break;
}
}
public function onTestMethodPassed(TestMethod $method) {
switch ($this->verbosity) {
case self::VERBOSITY_LOW:
break;
case self::VERBOSITY_HIGH:
case self::VERBOSITY_MEDIUM:
default:
$this->out('.');
break;
}
}
public function onTestMethodErred(TestMethod $method) {
switch ($this->verbosity) {
case self::VERBOSITY_LOW:
break;
case self::VERBOSITY_HIGH:
case self::VERBOSITY_MEDIUM:
default:
$this->out('E');
break;
}
}
public function onTestMethodIgnored(TestMethod $method) {
switch ($this->verbosity) {
case self::VERBOSITY_LOW:
break;
case self::VERBOSITY_HIGH:
case self::VERBOSITY_MEDIUM:
default:
$this->out('I');
break;
}
}
public function onFrameworkError($message) {
$this->err('ERROR: ' . $message);
}
public function onFrameworkWarning($message) {
if ($this->verbosity > self::VERBOSITY_LOW) {
$this->out('WARNING: ' . $message);
}
}
}
?>

View File

@ -3,7 +3,7 @@
/**
* Autoload manifest
*
* Autogenerated by manifester.php on 2009-06-12 23:55:38
* Autogenerated by manifester.php on 2009-06-13 01:14:12
*
* @package TUnit
* @version 0.1.0
@ -11,24 +11,29 @@
*/
return array(
'Assert' => 'TUnit/framework/Assert.php',
'Autoloader' => 'TUnit/util/Autoloader.php',
'CombinedCaseResult' => 'TUnit/framework/CombinedTestResult.php',
'ErredTest' => 'TUnit/framework/FailedTest.php',
'FailedTest' => 'TUnit/framework/FailedTest.php',
'FailedTestResult' => 'TUnit/framework/FailedTestResult.php',
'IgnoredTest' => 'TUnit/framework/FailedTest.php',
'IgnoredTestResult' => 'TUnit/framework/IgnoredTestResult.php',
'PassedTestResult' => 'TUnit/framework/PassedTestResult.php',
'TestCase' => 'TUnit/framework/TestCase.php',
'TestFailure' => 'TUnit/framework/FailedTest.php',
'TestListener' => 'TUnit/framework/TestListener.php',
'TestMethod' => 'TUnit/framework/TestMethod.php',
'TestReporter' => 'TUnit/framework/TestReporter.php',
'TestResult' => 'TUnit/framework/TestResult.php',
'TestRunner' => 'TUnit/framework/TestRunner.php',
'TestSuite' => 'TUnit/framework/TestSuite.php',
'Testable' => 'TUnit/framework/Testable.php'
'Assert' => 'TUnit/framework/Assert.php',
'Autoloader' => 'TUnit/util/Autoloader.php',
'Cli' => 'TUnit/util/cli.php',
'CliSwitch' => 'TUnit/util/cli.php',
'CliSwitchCollection' => 'TUnit/util/cli.php',
'CombinedTestResult' => 'TUnit/framework/CombinedTestResult.php',
'ConsoleListener' => 'TUnit/framework/listeners/ConsoleListener.php',
'ErredTest' => 'TUnit/framework/FailedTest.php',
'FailedTest' => 'TUnit/framework/FailedTest.php',
'FailedTestResult' => 'TUnit/framework/FailedTestResult.php',
'IgnoredTest' => 'TUnit/framework/FailedTest.php',
'IgnoredTestResult' => 'TUnit/framework/IgnoredTestResult.php',
'PassedTestResult' => 'TUnit/framework/PassedTestResult.php',
'TestCase' => 'TUnit/framework/TestCase.php',
'TestFailure' => 'TUnit/framework/FailedTest.php',
'TestListener' => 'TUnit/framework/TestListener.php',
'TestMethod' => 'TUnit/framework/TestMethod.php',
'TestReporter' => 'TUnit/framework/TestReporter.php',
'TestResult' => 'TUnit/framework/TestResult.php',
'TestRunner' => 'TUnit/framework/TestRunner.php',
'TestSuite' => 'TUnit/framework/TestSuite.php',
'Testable' => 'TUnit/framework/Testable.php',
'Usage' => 'TUnit/util/cli.php'
);
?>

214
src/TUnit/util/cli.php Normal file
View File

@ -0,0 +1,214 @@
<?php
class Cli {
private function __construct() {}
/**
* Parses command line arguments
*
* @param array $args
* @return array
*/
public static function parseArgs(array $args, CliSwitchCollection $switches) {
$parsed = array(
'switches' => array(),
'args' => array()
);
$last = null;
foreach ($args as $arg) {
if (strpos($arg, '-') === 0) {
$last = (substr($arg, 0, 2) === '--') ? substr($arg, 2) : substr($arg, 1);
$switch = $switches->getSwitch($last);
if ($switch !== null) {
$parsed['switches'][$switch->longName] = true;
}
} else if ($switch !== null) {
if ($switch->value !== null) {
$parsed['switches'][$switch->longName] = $arg;
} else {
$parsed['args'][] = $arg;
}
$switch = null;
} else {
$parsed['args'][] = $arg;
}
}
return $parsed;
}
}
class CliSwitch {
public $longName;
public $shortName;
public $required;
public $value;
public $description;
public function __construct($longName, $shortName = '', $required = true, $value = null, $description = '') {
$this->longName = $longName;
$this->shortName = $shortName;
$this->required = $required;
$this->value = $value;
$this->description = $description;
}
}
class CliSwitchCollection implements IteratorAggregate {
private $switches;
public function __construct() {
$this->switches = array();
}
public function addSwitch(CliSwitch $switch) {
$this->switches[] = $switch;
return $this;
}
public function getSwitch($longOrShortName) {
foreach ($this->switches as $switch) {
if ($switch->longName == $longOrShortName || $switch->shortName == $longOrShortName) {
return $switch;
}
}
return null;
}
public function segregateSwitches() {
$switches = array(
'required' => array(),
'optional' => array()
);
foreach ($this->switches as $switch) {
if ($switch->required) {
$switches['required'][] = $switch;
} else {
$switches['optional'][] = $switch;
}
}
return $switches;
}
public function getIterator() {
return new ArrayIterator($this->switches);
}
}
class Usage {
private $switches;
private $name;
private $script;
private $description;
private $copyright;
private $maxSwitchLength;
const LINE_LENGTH = 80;
public function __construct($name, $script, $description, $author = null, $date = null) {
$this->switches = array(array(), array());
$this->maxSwitchLength = 0;
$this->script = $script;
$this->name = $name;
$this->description = $description;
$this->copyright =
($date !== null)
? 'Copyright (c) ' . $date . (($author !== null) ? " $author" : '')
: (($author !== null) ? "by $author" : '');
}
public function __get($key) {
if ($key === 'switches') {
return $this->switches;
}
throw new InvalidArgumentException('Invalid property');
}
public function setSwitches(CliSwitchCollection $switches) {
$this->switches = $switches;
$this->maxSwitchLength = 0;
foreach ($switches->getIterator() as $switch) {
// + 2 for left padding
// + 2 for double-hyphen
$length = 2 + strlen($switch->longName) + 2;
// + 1 for left padding
// + 1 for hyphen
// + 1 for openening parenthesis
// + 1 for closing parenthesis
$length += (strlen($switch->shortName) > 0) ? 1 + 1 + 1 + strlen($switch->shortName) + 1 : 0;
//echo $length . "\n";
$this->maxSwitchLength = max($this->maxSwitchLength, $length);
}
//echo $this->maxSwitchLength; exit;
}
public function __toString() {
$this->maxSwitchLength += 2;
$usage = $this->name . "\n";
$usage .= (!empty($this->copyright)) ? ' ' . $this->copyright . "\n" : '';
$usage .= "\n";
$usage .= "USAGE\n";
$usageData = ' php ' . $this->script;
$switchData = "REQUIRED\n";
$switches = $this->switches->segregateSwitches();
foreach ($switches['required'] as $switch) {
$usageData .= ' --' . $switch->longName;
if ($switch->value !== null) {
$usageData .= ' ' . $switch->value;
}
$x = ' --' . $switch->longName;
if (!empty($switch->shortName)) {
$x .= str_repeat(' ', $this->maxSwitchLength - 5 - strlen($x)) . '(-' . $switch->shortName . ')';
}
$x .= str_repeat(' ' , $this->maxSwitchLength - strlen($x));
$x .= wordwrap($switch->description, self::LINE_LENGTH - strlen($x), "\n" . str_repeat(' ', strlen($x))) . "\n";
$switchData .= $x;
}
$switchData .= "\nOPTIONAL\n";
foreach ($switches['optional'] as $switch) {
$usageData .= ' [--' . $switch->longName;
if ($switch->value !== null) {
$usageData .= ' ' . $switch->value;
}
$usageData .= ']';
$x = ' --' . $switch->longName;
if (!empty($switch->shortName)) {
$x .= str_repeat(' ', $this->maxSwitchLength - 5 - strlen($x)) . '(-' . $switch->shortName . ')';
}
$x .= str_repeat(' ' , $this->maxSwitchLength - strlen($x));
$x .= wordwrap($switch->description, self::LINE_LENGTH - strlen($x), "\n" . str_repeat(' ', strlen($x))) . "\n";
$switchData .= $x;
}
$usage .= wordwrap($usageData, self::LINE_LENGTH - 2, "\n ");
$usage .= "\n\n" . $switchData . "\n";
return $usage;
}
}
?>

View File

@ -0,0 +1,51 @@
<?php
require_once 'cli.php';
require_once dirname(dirname(__FILE__)) . '/bootstrap.php';
$switches = new CliSwitchCollection();
//$switches->AddSwitch(new CliSwitch('ini-directive', 'd', false, 'key="value"', 'php.ini directives'))
array_shift($argv);
$args = Cli::parseArgs($argv, $switches);
//accumulate tests
$tests = array();
foreach ($args['args'] as $arg) {
$arg = realpath($arg);
if (is_file($arg)) {
require_once $arg;
$testClass = basename($arg, '.php');
if (!class_exists($testClass)) {
throw new Exception('The class "' . $testClass . '" does not exist in the file ' . $arg);
}
$testClass = new $testClass($testClass);
if ($testClass instanceof Testable) {
$tests[] = $testClasse;
}
} else if (is_dir($arg)) {
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($arg)) as $file) {
if ($file->isFile() && strpos($file->getPathName(), '.') === false) {
$file = $file->getPathName();
require_once $file;
$testClass = basename($file, '.php');
if (class_exists($testClass)) {
continue;
}
$testClass = new $testClass($testClass);
if ($testClass instanceof Testable) {
$tests[] = $testClasse;
}
}
}
}
}
$runner = new TestRunner(array(new TestSuite('Main Test Suite', $tests)), array(new ConsoleListener()));
$runner->runTests();
exit(0);
?>

2
src/tunit.bat Normal file
View File

@ -0,0 +1,2 @@
@echo off
php .\TUnit\util\entry_console.php %*