comments
This commit is contained in:
parent
06aaa82a09
commit
5ca59db858
@ -3,19 +3,17 @@
|
||||
/**
|
||||
* Autoloader
|
||||
*
|
||||
* @package Library
|
||||
* @subpackage Utilities
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
* @package TUnit
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bootstraps each NowhereConcave package via autoload
|
||||
*
|
||||
* @package Library
|
||||
* @subpackage Utilities
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
* @package TUnit
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
final class Autoloader {
|
||||
|
||||
|
@ -1,11 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP file iterators
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for recursively iterating over PHP files
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
class RecursivePhpFileIterator extends RecursiveFilterIterator {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @param mixed $dir
|
||||
*/
|
||||
public function __construct($dir) {
|
||||
parent::__construct(new RecursiveDirectoryIterator($dir));
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines acceptance criteria for iteration
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function accept() {
|
||||
return
|
||||
!$this->getInnerIterator()->isDot() &&
|
||||
@ -15,12 +50,38 @@
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over PHP files
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
class PhpFileIterator extends FilterIterator {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @param string $dir
|
||||
*/
|
||||
public function __construct($dir) {
|
||||
parent::__construct(new DirectoryIterator($dir));
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines acceptance criteria for iteration
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function accept() {
|
||||
return
|
||||
!$this->getInnerIterator()->isDot() &&
|
||||
|
@ -1,11 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RecursiveTestIterator
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for recursively iterating over test results
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
class RecursiveTestIterator extends ArrayIterator implements RecursiveIterator {
|
||||
|
||||
/**
|
||||
* Gets the children of the current iterator
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function getChildren() {
|
||||
return new self($this->current()->getTestResults());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the current iterator has any children
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function hasChildren() {
|
||||
return $this->current() instanceof CombinedTestResult;
|
||||
}
|
||||
|
@ -1,7 +1,37 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* TestAccumulator
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Accumulates test
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
class TestAccumulator {
|
||||
|
||||
/**
|
||||
* Gets all tests in the specified paths
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
* @uses getTestsFromDir()
|
||||
* @uses getTestsFromFile()
|
||||
*
|
||||
* @param array $paths
|
||||
* @param bool $recursive
|
||||
* @return array An array of {@link Testable}s
|
||||
*/
|
||||
public static function getTests(array $paths, $recursive = true) {
|
||||
$tests = array();
|
||||
|
||||
@ -17,6 +47,18 @@
|
||||
return $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all tests in the specified directory
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
* @uses getTestsFromFile()
|
||||
*
|
||||
* @param mixed $dir
|
||||
* @param bool $recursive
|
||||
* @return array
|
||||
*/
|
||||
public static function getTestsFromDir($dir, $recursive = true) {
|
||||
$iterator = ($recursive) ? new RecursivePhpFileIterator($dir) : new PhpFileIterator($dir);
|
||||
|
||||
@ -31,6 +73,16 @@
|
||||
return $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all tests from the specified file
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @param string $file
|
||||
* @return array
|
||||
*/
|
||||
public static function getTestsFromFile($file) {
|
||||
$tests = array();
|
||||
|
||||
|
@ -1,9 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Util
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Utilities
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
class Util {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
* @ignore
|
||||
*/
|
||||
private function __construct() {}
|
||||
|
||||
/**
|
||||
* Gets a human-readable version of an object
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @param mixed $var
|
||||
* @return string
|
||||
*/
|
||||
public static function export($var) {
|
||||
switch (strtolower(gettype($var))) {
|
||||
case 'object':
|
||||
@ -26,6 +61,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a parameter definition for a method
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @param ReflectionMethod $method
|
||||
* @return string
|
||||
*/
|
||||
public static function buildParameterDefinition(ReflectionMethod $method) {
|
||||
$paramList = '';
|
||||
foreach ($method->getParameters() as $i => $param) {
|
||||
@ -56,6 +101,17 @@
|
||||
return rtrim($paramList, ', ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Repairs a parameter name from ReflectionParameter->getName()
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $position
|
||||
* @return string
|
||||
*/
|
||||
private static function repairParameterName($name, $position) {
|
||||
if (empty($name)) {
|
||||
$name = 'param' . $position;
|
||||
@ -64,6 +120,17 @@
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a parameter list suitable for eval()
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
* @uses repairParameterName()
|
||||
*
|
||||
* @param ReflectionMethod $method
|
||||
* @return string
|
||||
*/
|
||||
public static function buildParameterNameList(ReflectionMethod $method) {
|
||||
$list = '';
|
||||
foreach ($method->getParameters() as $param) {
|
||||
@ -73,6 +140,16 @@
|
||||
return rtrim($list, ', ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Flattens a multi-dimensional array into one dimension
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @param mixed $arr
|
||||
* @return array
|
||||
*/
|
||||
public static function arrayFlatten($arr) {
|
||||
$flattened = array();
|
||||
if (is_array($arr)) {
|
||||
@ -86,6 +163,17 @@
|
||||
return $flattened;
|
||||
}
|
||||
|
||||
/**
|
||||
* DGets the number of all test suites, cases and methods
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
* @uses mergeTestCount()
|
||||
*
|
||||
* @param array $tests
|
||||
* @return array An array with keys "suite", "case" and "method"
|
||||
*/
|
||||
public static function countTests(array $tests) {
|
||||
$counts = array(
|
||||
'suite' => 0,
|
||||
@ -108,6 +196,17 @@
|
||||
return $counts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by countTests()
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @param array $arr1
|
||||
* @param array $arr2
|
||||
* @return array
|
||||
*/
|
||||
private static function mergeTestCount(array $arr1, array $arr2) {
|
||||
$arr1['suite'] += $arr2['suite'];
|
||||
$arr1['case'] += $arr2['case'];
|
||||
@ -115,6 +214,19 @@
|
||||
return $arr1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a method closure
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
* @link http://php.net/manual/en/language.oop5.reflection.php#90964
|
||||
*
|
||||
* @param object $object
|
||||
* @param string $method
|
||||
* @throws InvalidArgumentException
|
||||
* @return lambda
|
||||
*/
|
||||
public static function getClosure($object, $method) {
|
||||
if (!is_object($object)) {
|
||||
throw new InvalidArgumentException('1st argument must be an object');
|
||||
|
@ -1,7 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Cli, Usage, CliSwitch, CliSwitchCollection
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Cli helper
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
class Cli {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
private function __construct() {}
|
||||
|
||||
/**
|
||||
@ -44,31 +68,106 @@
|
||||
}
|
||||
|
||||
class CliSwitch {
|
||||
|
||||
/**
|
||||
* Long name of the switch
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $longName;
|
||||
|
||||
/**
|
||||
* Short name of the switch
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $shortName;
|
||||
|
||||
/**
|
||||
* Shether this switch is required or optional
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $required;
|
||||
|
||||
/**
|
||||
* The value of the switch
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Description of the switch
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $description;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @param string $longName
|
||||
* @param string $shortName
|
||||
* @param bool $required
|
||||
* @param string $value
|
||||
* @param string $description
|
||||
*/
|
||||
public function __construct($longName, $shortName = '', $required = true, $value = null, $description = '') {
|
||||
$this->longName = $longName;
|
||||
$this->shortName = $shortName;
|
||||
$this->required = $required;
|
||||
$this->value = $value;
|
||||
$this->longName = $longName;
|
||||
$this->shortName = $shortName;
|
||||
$this->required = $required;
|
||||
$this->value = $value;
|
||||
$this->description = $description;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a collection of {@link CliSwitch}es
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
class CliSwitchCollection implements IteratorAggregate {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $switches;
|
||||
|
||||
/**
|
||||
* @var CliSwitch
|
||||
*/
|
||||
private $switchArg;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->switches = array();
|
||||
$this->switches = array();
|
||||
$this->switchArg = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a switch to the collection
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @param CliSwitch $switch
|
||||
* @return CliSwitchCollection
|
||||
*/
|
||||
public function addSwitch(CliSwitch $switch) {
|
||||
if ($switch->longName === null) {
|
||||
$this->switchArg = $switch;
|
||||
@ -79,6 +178,16 @@
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a switch by its short or long name
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @param string $longOrShortName
|
||||
* @return CliSwitch|null
|
||||
*/
|
||||
public function getSwitch($longOrShortName) {
|
||||
foreach ($this->switches as $switch) {
|
||||
if ($switch->longName == $longOrShortName || $switch->shortName == $longOrShortName) {
|
||||
@ -89,6 +198,15 @@
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Segregates the switches into required and optional
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @return array Array with keys "required" and "optional"
|
||||
*/
|
||||
public function segregateSwitches() {
|
||||
$switches = array(
|
||||
'required' => array(),
|
||||
@ -105,27 +223,102 @@
|
||||
return $switches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the switch representing the arguments
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @return CliSwitch
|
||||
*/
|
||||
public function getSwitchArg() {
|
||||
return $this->switchArg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an iterator
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->switches);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helpful class for printing usage
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
class Usage {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $switches;
|
||||
|
||||
/**
|
||||
* Name of the program
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* Name of the script
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $script;
|
||||
|
||||
/**
|
||||
* Description of the program
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* Copyright information
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $copyright;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $maxSwitchLength;
|
||||
|
||||
/**
|
||||
* Max line length
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const LINE_LENGTH = 80;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $script
|
||||
* @param string $description
|
||||
* @param string $author
|
||||
* @param string $date
|
||||
*/
|
||||
public function __construct($name, $script, $description, $author = null, $date = null) {
|
||||
$this->switches = array(array(), array());
|
||||
$this->maxSwitchLength = 0;
|
||||
@ -138,6 +331,18 @@
|
||||
: (($author !== null) ? "by $author" : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic function __get
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*
|
||||
* @param mixed $key
|
||||
* @throws InvalidArgumentException
|
||||
* @return mixed
|
||||
* @ignore
|
||||
*/
|
||||
public function __get($key) {
|
||||
if ($key === 'switches') {
|
||||
return $this->switches;
|
||||
@ -146,6 +351,16 @@
|
||||
throw new InvalidArgumentException('Invalid property');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the switch collection
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
* @uses CliSwitchCollection::getIterator()
|
||||
*
|
||||
* @param CliSwitchCollection $switches
|
||||
*/
|
||||
public function setSwitches(CliSwitchCollection $switches) {
|
||||
$this->switches = $switches;
|
||||
|
||||
@ -165,6 +380,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string representation of this object
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
* @uses CliSwitchCollection::segregateSwitches()
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
$this->maxSwitchLength += 2;
|
||||
$usage = $this->name . "\n";
|
||||
|
@ -1,8 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Entry point for console test runner
|
||||
*
|
||||
* @package TUnit
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @see Cli
|
||||
*/
|
||||
require_once 'cli.php';
|
||||
|
||||
/**
|
||||
* Bootstraps TUnit
|
||||
*/
|
||||
require_once dirname(dirname(__FILE__)) . '/bootstrap.php';
|
||||
|
||||
/**
|
||||
* Prints usage
|
||||
*
|
||||
* @author Tommy Montgomery
|
||||
* @version 1.0
|
||||
* @since 1.0
|
||||
*/
|
||||
function usage() {
|
||||
$usage = new Usage(
|
||||
Product::NAME . ' ' . Product::VERSION . ' (' . Product::DATE . ')',
|
||||
|
Loading…
Reference in New Issue
Block a user