type, math and array constraints

This commit is contained in:
tmont 2009-07-08 08:42:50 +00:00
parent 2341bf20ea
commit 16d163254c
8 changed files with 706 additions and 62 deletions

View File

@ -232,6 +232,350 @@
self::evaluate(self::negate(new NullConstraint($value)), $message);
}
/**
* Asserts that a value is a file
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isFile($value, $message = '') {
self::evaluate(new IsFileConstraint($value), $message);
}
/**
* Asserts that a value is not a file
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isNotFile($value, $message = '') {
self::evaluate(self::negate(new IsFileConstraint($value)), $message);
}
/**
* Asserts that a value is a directory
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isDirectory($value, $message = '') {
self::evaluate(new IsDirectoryConstraint($value), $message);
}
/**
* Asserts that a value is not a directory
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isNotDirectory($value, $message = '') {
self::evaluate(self::negate(new IsDirectoryConstraint($value)), $message);
}
/**
* Asserts that a value is an integer
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isInt($value, $message = '') {
self::evaluate(new TypeConstraint('int', $value), $message);
}
/**
* Asserts that a value is not an integer
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isNotInt($value, $message = '') {
self::evaluate(self::negate(new TypeConstraint('int', $value)), $message);
}
/**
* Asserts that a value is a boolean
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isBool($value, $message = '') {
self::evaluate(new TypeConstraint('bool', $value), $message);
}
/**
* Asserts that a value is not a boolean
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isNotBool($value, $message = '') {
self::evaluate(self::negate(new TypeConstraint('bool', $value)), $message);
}
/**
* Asserts that a value is a float
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isFloat($value, $message = '') {
self::evaluate(new TypeConstraint('float', $value), $message);
}
/**
* Asserts that a value is not a float
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isNotFloat($value, $message = '') {
self::evaluate(self::negate(new TypeConstraint('float', $value)), $message);
}
/**
* Asserts that a value is an array
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isArray($value, $message = '') {
self::evaluate(new TypeConstraint('array', $value), $message);
}
/**
* Asserts that a value is not an array
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isNotArray($value, $message = '') {
self::evaluate(self::negate(new TypeConstraint('array', $value)), $message);
}
/**
* Asserts that a value is a string
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isString($value, $message = '') {
self::evaluate(new TypeConstraint('string', $value), $message);
}
/**
* Asserts that a value is not a string
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function isNotString($value, $message = '') {
self::evaluate(self::negate(new TypeConstraint('string', $value)), $message);
}
/**
* Asserts that a value is numeric
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function numeric($value, $message = '') {
self::evaluate(new TypeConstraint('numeric', $value), $message);
}
/**
* Asserts that a value is not numeric
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param string $message
*/
public static function notNumeric($value, $message = '') {
self::evaluate(self::negate(new TypeConstraint('numeric', $value)), $message);
}
/**
* Asserts that a value is greater than an expected value
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $expected
* @param mixed $value
* @param string $message
*/
public static function greaterThan($expected, $actual, $message = '') {
self::evaluate(new GreaterThanConstraint($expected, $actual), $message);
}
/**
* Asserts that a value is greater than or equal to an expected value
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $expected
* @param mixed $value
* @param string $message
*/
public static function greaterThanOrEqualTo($expected, $actual, $message = '') {
self::evaluate(new GreaterThanOrEqualToConstraint($expected, $actual), $message);
}
/**
* Asserts that a value is less than an expected value
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $expected
* @param mixed $value
* @param string $message
*/
public static function lessThan($expected, $actual, $message = '') {
self::evaluate(new LessThanConstraint($expected, $actual), $message);
}
/**
* Asserts that a value is less than or equal to an expected value
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $expected
* @param mixed $value
* @param string $message
*/
public static function lessThanOrEqualTo($expected, $actual, $message = '') {
self::evaluate(new LessThanOrEqualToConstraint($expected, $actual), $message);
}
/**
* Asserts that a key exists in an array
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $key
* @param array $array
* @param string $message
*/
public static function arrayHasKey($key, array $array, $message = '') {
self::evaluate(new ArrayHasKeyConstraint($key, $array), $message);
}
/**
* Asserts that a key does not exist in an array
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $key
* @param array $array
* @param string $message
*/
public static function arrayNotHasKey($key, array $array, $message = '') {
self::evaluate(self::negate(new ArrayHasKeyConstraint($key, $array)), $message);
}
/**
* Asserts that an array contains a value
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param array $array
* @param string $message
*/
public static function arrayHasValue($value, array $array, $message = '') {
self::evaluate(new ArrayHasValueConstraint($value, $array), $message);
}
/**
* Asserts that an array does not contain a value
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @param mixed $value
* @param array $array
* @param string $message
*/
public static function arrayNotHasValue($value, array $array, $message = '') {
self::evaluate(self::negate(new ArrayHasValueConstraint($value, $array)), $message);
}
}
?>

View File

@ -0,0 +1,35 @@
<?php
class ArrayHasKeyConstraint extends DefaultConstraint {
public function __construct($key, array $array, $message = '') {
parent::__construct($key, $array, $message);
}
public function evaluate() {
return array_key_exists($this->expected, $this->actual);
}
protected function getFailureMessage() {
return Util::export($this->actual) . " has key \"$this->expected\"";
}
}
class ArrayHasValueConstraint extends DefaultConstraint {
public function __construct($value, array $array, $message = '') {
parent::__construct($value, $array, $message);
}
public function evaluate() {
return in_array($this->expected, $this->actual);
}
protected function getFailureMessage() {
return 'the value ' . Util::export($this->expected) . ' is in the array ' . Util::export($this->actual);
}
}
?>

View File

@ -0,0 +1,51 @@
<?php
class GreaterThanConstraint extends DefaultConstraint {
public function evaluate() {
return $this->actual > $this->expected;
}
protected function getFailureMessage() {
return $this->actual . ' is greater than ' . $this->expected;
}
}
class GreaterThanOrEqualToConstraint extends DefaultConstraint {
public function evaluate() {
return $this->actual >= $this->expected;
}
protected function getFailureMessage() {
return $this->actual . ' is greater than or equal to ' . $this->expected;
}
}
class LessThanConstraint extends DefaultConstraint {
public function evaluate() {
return $this->actual < $this->expected;
}
protected function getFailureMessage() {
return $this->actual . ' is less than ' . $this->expected;
}
}
class LessThanOrEqualToConstraint extends DefaultConstraint {
public function evaluate() {
return $this->actual <= $this->expected;
}
protected function getFailureMessage() {
return $this->actual . ' is less than or equal to ' . $this->expected;
}
}
?>

View File

@ -108,10 +108,12 @@
protected function negateString($string) {
return str_replace(
array(
' is '
' is ',
' has '
),
array(
' is not '
' is not ',
' has not '
),
$string
);

View File

@ -230,5 +230,81 @@
}
}
/**
* Constraint for asserting that a value is a file
*
* @package Testify
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*/
class IsFileConstraint extends SimpleConstraint {
/**
* {@inheritdoc}
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @return bool
*/
public function evaluate() {
return is_file($this->value);
}
/**
* {@inheritdoc}
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @return string
*/
protected function getFailureMessage() {
return Util::export($this->value) . ' is a file';
}
}
/**
* Constraint for asserting that a value is a directory
*
* @package Testify
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*/
class IsDirectoryConstraint extends SimpleConstraint {
/**
* {@inheritdoc}
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @return bool
*/
public function evaluate() {
return is_dir($this->value);
}
/**
* {@inheritdoc}
*
* @author Tommy Montgomery
* @version 1.0
* @since 1.0
*
* @return string
*/
protected function getFailureMessage() {
return Util::export($this->value) . ' is a directory';
}
}
?>

View File

@ -0,0 +1,28 @@
<?php
class TypeConstraint extends SimpleConstraint {
protected $callback;
public function __construct($type, $value) {
parent::__construct($value);
if (!function_exists('is_' . $type)) {
throw new InvalidArgumentException('Invalid type constraint: ' . $type);
}
$this->callback = 'is_' . strtolower($type);
}
public function evaluate() {
return call_user_func($this->callback, $this->value);
}
protected function getFailureMessage() {
$type = substr($this->callback, strpos($this->type, 'is_') + 3);
return Util::export($this->value) . " is of type \"$type\"";
}
}
?>

View File

@ -3,72 +3,81 @@
/**
* Autoload manifest
*
* Autogenerated by manifester.php on 2009-07-01 00:19:28
* Autogenerated by manifester.php on 2009-07-08 01:27:37
*
* @package Testify
* @version 0.6.0
* @version 0.7.0
* @since 1.0
*/
return array(
'Assert' => 'Testify/framework/Assert.php',
'Autoloader' => 'Testify/util/Autoloader.php',
'Cli' => 'Testify/util/cli.php',
'CliSwitch' => 'Testify/util/cli.php',
'CliSwitchCollection' => 'Testify/util/cli.php',
'CombinedTestResult' => 'Testify/framework/result/CombinedTestResult.php',
'ConsoleListener' => 'Testify/framework/listeners/ConsoleListener.php',
'ConsoleTestRunner' => 'Testify/framework/ConsoleTestRunner.php',
'Constraint' => 'Testify/framework/constraints/Constraint.php',
'CoverageDriver' => 'Testify/framework/reporting/CoverageGraphs.php',
'CoverageFilter' => 'Testify/framework/reporting/CoverageFilter.php',
'CoveragePalette' => 'Testify/framework/reporting/CoverageGraphs.php',
'CoveragePieChart' => 'Testify/framework/reporting/CoverageGraphs.php',
'CoverageRenderer' => 'Testify/framework/reporting/CoverageGraphs.php',
'CoverageReporter' => 'Testify/framework/reporting/CoverageReporter.php',
'DefaultConstraint' => 'Testify/framework/constraints/DefaultConstraint.php',
'EmptyConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'EqualConstraint' => 'Testify/framework/constraints/EqualConstraint.php',
'ErredTest' => 'Testify/framework/result/FailedTest.php',
'ErredTestResult' => 'Testify/framework/result/SingleTestResults.php',
'FailedTest' => 'Testify/framework/result/FailedTest.php',
'FailedTestResult' => 'Testify/framework/result/SingleTestResults.php',
'FalseConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'IdenticalConstraint' => 'Testify/framework/constraints/IdenticalConstraint.php',
'IgnoredTest' => 'Testify/framework/result/FailedTest.php',
'IgnoredTestResult' => 'Testify/framework/result/SingleTestResults.php',
'InvalidOptionException' => 'Testify/framework/exceptions/Exceptions.php',
'InvocationExpectation' => 'Testify/framework/mock/InvocationExpectation.php',
'InvocationTracker' => 'Testify/framework/mock/InvocationTracker.php',
'IssetConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'MockHandler' => 'Testify/framework/mock/MockHandler.php',
'MockInvocation' => 'Testify/framework/mock/MockInvocation.php',
'MockObject' => 'Testify/framework/mock/MockObjectCreator.php',
'MockObjectCreator' => 'Testify/framework/mock/MockObjectCreator.php',
'MockRegistry' => 'Testify/framework/mock/MockRegistry.php',
'NotConstraint' => 'Testify/framework/constraints/NotConstraint.php',
'NullConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'PassedTestResult' => 'Testify/framework/result/SingleTestResults.php',
'PhpFileIterator' => 'Testify/util/PhpFileIterator.php',
'Product' => 'Testify/util/Product.php',
'RecursivePhpFileIterator' => 'Testify/util/PhpFileIterator.php',
'RecursiveTestIterator' => 'Testify/util/RecursiveTestIterator.php',
'RecursivelyCountable' => 'Testify/framework/test/Testable.php',
'SimpleConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'SingleTestResult' => 'Testify/framework/result/SingleTestResults.php',
'TestAccumulator' => 'Testify/util/TestAccumulator.php',
'TestCase' => 'Testify/framework/test/TestCase.php',
'TestFailure' => 'Testify/framework/result/FailedTest.php',
'TestListener' => 'Testify/framework/listeners/TestListener.php',
'TestMethod' => 'Testify/framework/test/TestMethod.php',
'TestResult' => 'Testify/framework/result/TestResult.php',
'TestRunner' => 'Testify/framework/BaseTestRunner.php',
'TestSuite' => 'Testify/framework/test/TestSuite.php',
'Testable' => 'Testify/framework/test/Testable.php',
'TestifyException' => 'Testify/framework/exceptions/Exceptions.php',
'TrueConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'Usage' => 'Testify/util/cli.php',
'Util' => 'Testify/util/Util.php'
'ArrayHasKeyConstraint' => 'Testify/framework/constraints/ArrayConstraints.php',
'ArrayHasValueConstraint' => 'Testify/framework/constraints/ArrayConstraints.php',
'Assert' => 'Testify/framework/Assert.php',
'Autoloader' => 'Testify/util/Autoloader.php',
'Cli' => 'Testify/util/cli.php',
'CliSwitch' => 'Testify/util/cli.php',
'CliSwitchCollection' => 'Testify/util/cli.php',
'CombinedTestResult' => 'Testify/framework/result/CombinedTestResult.php',
'ConsoleListener' => 'Testify/framework/listeners/ConsoleListener.php',
'ConsoleTestRunner' => 'Testify/framework/ConsoleTestRunner.php',
'Constraint' => 'Testify/framework/constraints/Constraint.php',
'CoverageDriver' => 'Testify/framework/reporting/CoverageGraphs.php',
'CoverageFilter' => 'Testify/framework/reporting/CoverageFilter.php',
'CoveragePalette' => 'Testify/framework/reporting/CoverageGraphs.php',
'CoveragePieChart' => 'Testify/framework/reporting/CoverageGraphs.php',
'CoverageRenderer' => 'Testify/framework/reporting/CoverageGraphs.php',
'CoverageReporter' => 'Testify/framework/reporting/CoverageReporter.php',
'DefaultConstraint' => 'Testify/framework/constraints/DefaultConstraint.php',
'EmptyConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'EqualConstraint' => 'Testify/framework/constraints/EqualConstraint.php',
'ErredTest' => 'Testify/framework/result/FailedTest.php',
'ErredTestResult' => 'Testify/framework/result/SingleTestResults.php',
'FailedTest' => 'Testify/framework/result/FailedTest.php',
'FailedTestResult' => 'Testify/framework/result/SingleTestResults.php',
'FalseConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'GreaterThanConstraint' => 'Testify/framework/constraints/MathConstraints.php',
'GreaterThanOrEqualToConstraint' => 'Testify/framework/constraints/MathConstraints.php',
'IdenticalConstraint' => 'Testify/framework/constraints/IdenticalConstraint.php',
'IgnoredTest' => 'Testify/framework/result/FailedTest.php',
'IgnoredTestResult' => 'Testify/framework/result/SingleTestResults.php',
'InvalidOptionException' => 'Testify/framework/exceptions/Exceptions.php',
'InvocationExpectation' => 'Testify/framework/mock/InvocationExpectation.php',
'InvocationTracker' => 'Testify/framework/mock/InvocationTracker.php',
'IsDirectoryConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'IsFileConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'IssetConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'LessThanConstraint' => 'Testify/framework/constraints/MathConstraints.php',
'LessThanOrEqualToConstraint' => 'Testify/framework/constraints/MathConstraints.php',
'MockHandler' => 'Testify/framework/mock/MockHandler.php',
'MockInvocation' => 'Testify/framework/mock/MockInvocation.php',
'MockObject' => 'Testify/framework/mock/MockObjectCreator.php',
'MockObjectCreator' => 'Testify/framework/mock/MockObjectCreator.php',
'MockRegistry' => 'Testify/framework/mock/MockRegistry.php',
'NotConstraint' => 'Testify/framework/constraints/NotConstraint.php',
'NullConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'PassedTestResult' => 'Testify/framework/result/SingleTestResults.php',
'PhpFileIterator' => 'Testify/util/PhpFileIterator.php',
'Product' => 'Testify/util/Product.php',
'RecursivePhpFileIterator' => 'Testify/util/PhpFileIterator.php',
'RecursiveTestIterator' => 'Testify/util/RecursiveTestIterator.php',
'RecursivelyCountable' => 'Testify/framework/test/Testable.php',
'SimpleConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'SingleTestResult' => 'Testify/framework/result/SingleTestResults.php',
'TestAccumulator' => 'Testify/util/TestAccumulator.php',
'TestCase' => 'Testify/framework/test/TestCase.php',
'TestFailure' => 'Testify/framework/result/FailedTest.php',
'TestListener' => 'Testify/framework/listeners/TestListener.php',
'TestMethod' => 'Testify/framework/test/TestMethod.php',
'TestResult' => 'Testify/framework/result/TestResult.php',
'TestRunner' => 'Testify/framework/BaseTestRunner.php',
'TestSuite' => 'Testify/framework/test/TestSuite.php',
'Testable' => 'Testify/framework/test/Testable.php',
'TestifyException' => 'Testify/framework/exceptions/Exceptions.php',
'TrueConstraint' => 'Testify/framework/constraints/SimpleConstraints.php',
'TypeConstraint' => 'Testify/framework/constraints/TypeConstraint.php',
'Usage' => 'Testify/util/cli.php',
'Util' => 'Testify/util/Util.php'
);
?>

View File

@ -60,6 +60,105 @@
Assert::equal('array[3]', Util::export(array(1,2,3)));
}
/**
* @test
*/
public function buildParameterDefinition() {
$refMethod = new ReflectionMethod($this, __FUNCTION__);
Assert::isEmpty(Util::buildParameterDefinition($refMethod));
$refMethod = new ReflectionMethod('ReflectionMethod', 'invokeArgs');
Assert::equal('$object, array $args', Util::buildParameterDefinition($refMethod));
$refMethod = new ReflectionMethod('ReflectionClass', 'getStaticPropertyValue');
Assert::equal('$name, $default = null', Util::buildParameterDefinition($refMethod));
}
/**
* @test
*/
public function arrayFlatten() {
$arr = array(
'foo' => 'bar',
7 => array(
0 => array(
1 => array(
2 => array(
3
)
)
),
'baz',
'bat' => array(
'foobie'
)
),
8,
'yay' => array()
);
$expected = array('bar', 3, 'baz', 'foobie', 8);
Assert::identical($expected, Util::arrayFlatten($arr), 'arrays are not identical');
}
/**
* @test
*/
public function arithmetic() {
Assert::greaterThan(0, 1);
Assert::greaterThanOrEqualTo(0, 0);
Assert::lessThan(1, 0);
Assert::lessThanOrEqualTo(0, 0);
}
/**
* @test
*/
public function types() {
Assert::isInt(0);
Assert::isNotInt('0');
Assert::isFloat(1.5);
Assert::isNotFloat(true);
Assert::isString('foo');
Assert::isNotString(1);
Assert::isBool(false);
Assert::isNotBool(1);
Assert::isArray(array());
Assert::isNotArray(new stdClass());
Assert::numeric('1.5');
Assert::numeric(1.0);
Assert::numeric(1);
Assert::numeric(1e10);
Assert::numeric(0x12);
Assert::notNumeric(array());
}
/**
* @test
*/
public function arrays() {
$arr = array(
'foo' => 'bar',
7 => new stdClass()
);
Assert::arrayHasKey('foo', $arr);
Assert::arrayHasKey(7, $arr);
Assert::arrayNotHasKey('bar', $arr);
Assert::arrayNotHasKey(0, $arr);
Assert::arrayHasValue('bar', $arr);
Assert::arrayHasValue(new stdClass(), $arr);
Assert::arrayNotHasValue(null, $arr);
}
}
?>