Pressroom template verwijderd, website naar root van repo

This commit is contained in:
2020-03-22 15:30:52 +01:00
parent 2cb6a77425
commit f3d1c41e91
7620 changed files with 0 additions and 186900 deletions

View File

@@ -0,0 +1,805 @@
<?php
/*
Copyright (c) 2009-2010 hamcrest.org
*/
// This file is generated from the static method @factory doctags.
if (!function_exists('assertThat')) {
/**
* Make an assertion and throw {@link Hamcrest_AssertionError} if it fails.
*
* Example:
* <pre>
* //With an identifier
* assertThat("assertion identifier", $apple->flavour(), equalTo("tasty"));
* //Without an identifier
* assertThat($apple->flavour(), equalTo("tasty"));
* //Evaluating a boolean expression
* assertThat("some error", $a > $b);
* </pre>
*/
function assertThat()
{
$args = func_get_args();
call_user_func_array(
array('Hamcrest\MatcherAssert', 'assertThat'),
$args
);
}
}
if (!function_exists('anArray')) { /**
* Evaluates to true only if each $matcher[$i] is satisfied by $array[$i].
*/
function anArray(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Arrays\IsArray', 'anArray'), $args);
}
}
if (!function_exists('hasItemInArray')) { /**
* Evaluates to true if any item in an array satisfies the given matcher.
*
* @param mixed $item as a {@link Hamcrest\Matcher} or a value.
*
* @return \Hamcrest\Arrays\IsArrayContaining
*/
function hasItemInArray($item)
{
return \Hamcrest\Arrays\IsArrayContaining::hasItemInArray($item);
}
}
if (!function_exists('hasValue')) { /**
* Evaluates to true if any item in an array satisfies the given matcher.
*
* @param mixed $item as a {@link Hamcrest\Matcher} or a value.
*
* @return \Hamcrest\Arrays\IsArrayContaining
*/
function hasValue($item)
{
return \Hamcrest\Arrays\IsArrayContaining::hasItemInArray($item);
}
}
if (!function_exists('arrayContainingInAnyOrder')) { /**
* An array with elements that match the given matchers.
*/
function arrayContainingInAnyOrder(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Arrays\IsArrayContainingInAnyOrder', 'arrayContainingInAnyOrder'), $args);
}
}
if (!function_exists('containsInAnyOrder')) { /**
* An array with elements that match the given matchers.
*/
function containsInAnyOrder(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Arrays\IsArrayContainingInAnyOrder', 'arrayContainingInAnyOrder'), $args);
}
}
if (!function_exists('arrayContaining')) { /**
* An array with elements that match the given matchers in the same order.
*/
function arrayContaining(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Arrays\IsArrayContainingInOrder', 'arrayContaining'), $args);
}
}
if (!function_exists('contains')) { /**
* An array with elements that match the given matchers in the same order.
*/
function contains(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Arrays\IsArrayContainingInOrder', 'arrayContaining'), $args);
}
}
if (!function_exists('hasKeyInArray')) { /**
* Evaluates to true if any key in an array matches the given matcher.
*
* @param mixed $key as a {@link Hamcrest\Matcher} or a value.
*
* @return \Hamcrest\Arrays\IsArrayContainingKey
*/
function hasKeyInArray($key)
{
return \Hamcrest\Arrays\IsArrayContainingKey::hasKeyInArray($key);
}
}
if (!function_exists('hasKey')) { /**
* Evaluates to true if any key in an array matches the given matcher.
*
* @param mixed $key as a {@link Hamcrest\Matcher} or a value.
*
* @return \Hamcrest\Arrays\IsArrayContainingKey
*/
function hasKey($key)
{
return \Hamcrest\Arrays\IsArrayContainingKey::hasKeyInArray($key);
}
}
if (!function_exists('hasKeyValuePair')) { /**
* Test if an array has both an key and value in parity with each other.
*/
function hasKeyValuePair($key, $value)
{
return \Hamcrest\Arrays\IsArrayContainingKeyValuePair::hasKeyValuePair($key, $value);
}
}
if (!function_exists('hasEntry')) { /**
* Test if an array has both an key and value in parity with each other.
*/
function hasEntry($key, $value)
{
return \Hamcrest\Arrays\IsArrayContainingKeyValuePair::hasKeyValuePair($key, $value);
}
}
if (!function_exists('arrayWithSize')) { /**
* Does array size satisfy a given matcher?
*
* @param \Hamcrest\Matcher|int $size as a {@link Hamcrest\Matcher} or a value.
*
* @return \Hamcrest\Arrays\IsArrayWithSize
*/
function arrayWithSize($size)
{
return \Hamcrest\Arrays\IsArrayWithSize::arrayWithSize($size);
}
}
if (!function_exists('emptyArray')) { /**
* Matches an empty array.
*/
function emptyArray()
{
return \Hamcrest\Arrays\IsArrayWithSize::emptyArray();
}
}
if (!function_exists('nonEmptyArray')) { /**
* Matches an empty array.
*/
function nonEmptyArray()
{
return \Hamcrest\Arrays\IsArrayWithSize::nonEmptyArray();
}
}
if (!function_exists('emptyTraversable')) { /**
* Returns true if traversable is empty.
*/
function emptyTraversable()
{
return \Hamcrest\Collection\IsEmptyTraversable::emptyTraversable();
}
}
if (!function_exists('nonEmptyTraversable')) { /**
* Returns true if traversable is not empty.
*/
function nonEmptyTraversable()
{
return \Hamcrest\Collection\IsEmptyTraversable::nonEmptyTraversable();
}
}
if (!function_exists('traversableWithSize')) { /**
* Does traversable size satisfy a given matcher?
*/
function traversableWithSize($size)
{
return \Hamcrest\Collection\IsTraversableWithSize::traversableWithSize($size);
}
}
if (!function_exists('allOf')) { /**
* Evaluates to true only if ALL of the passed in matchers evaluate to true.
*/
function allOf(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Core\AllOf', 'allOf'), $args);
}
}
if (!function_exists('anyOf')) { /**
* Evaluates to true if ANY of the passed in matchers evaluate to true.
*/
function anyOf(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Core\AnyOf', 'anyOf'), $args);
}
}
if (!function_exists('noneOf')) { /**
* Evaluates to false if ANY of the passed in matchers evaluate to true.
*/
function noneOf(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Core\AnyOf', 'noneOf'), $args);
}
}
if (!function_exists('both')) { /**
* This is useful for fluently combining matchers that must both pass.
* For example:
* <pre>
* assertThat($string, both(containsString("a"))->andAlso(containsString("b")));
* </pre>
*/
function both(\Hamcrest\Matcher $matcher)
{
return \Hamcrest\Core\CombinableMatcher::both($matcher);
}
}
if (!function_exists('either')) { /**
* This is useful for fluently combining matchers where either may pass,
* for example:
* <pre>
* assertThat($string, either(containsString("a"))->orElse(containsString("b")));
* </pre>
*/
function either(\Hamcrest\Matcher $matcher)
{
return \Hamcrest\Core\CombinableMatcher::either($matcher);
}
}
if (!function_exists('describedAs')) { /**
* Wraps an existing matcher and overrides the description when it fails.
*/
function describedAs(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Core\DescribedAs', 'describedAs'), $args);
}
}
if (!function_exists('everyItem')) { /**
* @param Matcher $itemMatcher
* A matcher to apply to every element in an array.
*
* @return \Hamcrest\Core\Every
* Evaluates to TRUE for a collection in which every item matches $itemMatcher
*/
function everyItem(\Hamcrest\Matcher $itemMatcher)
{
return \Hamcrest\Core\Every::everyItem($itemMatcher);
}
}
if (!function_exists('hasToString')) { /**
* Does array size satisfy a given matcher?
*/
function hasToString($matcher)
{
return \Hamcrest\Core\HasToString::hasToString($matcher);
}
}
if (!function_exists('is')) { /**
* Decorates another Matcher, retaining the behavior but allowing tests
* to be slightly more expressive.
*
* For example: assertThat($cheese, equalTo($smelly))
* vs. assertThat($cheese, is(equalTo($smelly)))
*/
function is($value)
{
return \Hamcrest\Core\Is::is($value);
}
}
if (!function_exists('anything')) { /**
* This matcher always evaluates to true.
*
* @param string $description A meaningful string used when describing itself.
*
* @return \Hamcrest\Core\IsAnything
*/
function anything($description = 'ANYTHING')
{
return \Hamcrest\Core\IsAnything::anything($description);
}
}
if (!function_exists('hasItem')) { /**
* Test if the value is an array containing this matcher.
*
* Example:
* <pre>
* assertThat(array('a', 'b'), hasItem(equalTo('b')));
* //Convenience defaults to equalTo()
* assertThat(array('a', 'b'), hasItem('b'));
* </pre>
*/
function hasItem(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Core\IsCollectionContaining', 'hasItem'), $args);
}
}
if (!function_exists('hasItems')) { /**
* Test if the value is an array containing elements that match all of these
* matchers.
*
* Example:
* <pre>
* assertThat(array('a', 'b', 'c'), hasItems(equalTo('a'), equalTo('b')));
* </pre>
*/
function hasItems(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Core\IsCollectionContaining', 'hasItems'), $args);
}
}
if (!function_exists('equalTo')) { /**
* Is the value equal to another value, as tested by the use of the "=="
* comparison operator?
*/
function equalTo($item)
{
return \Hamcrest\Core\IsEqual::equalTo($item);
}
}
if (!function_exists('identicalTo')) { /**
* Tests of the value is identical to $value as tested by the "===" operator.
*/
function identicalTo($value)
{
return \Hamcrest\Core\IsIdentical::identicalTo($value);
}
}
if (!function_exists('anInstanceOf')) { /**
* Is the value an instance of a particular type?
* This version assumes no relationship between the required type and
* the signature of the method that sets it up, for example in
* <code>assertThat($anObject, anInstanceOf('Thing'));</code>
*/
function anInstanceOf($theClass)
{
return \Hamcrest\Core\IsInstanceOf::anInstanceOf($theClass);
}
}
if (!function_exists('any')) { /**
* Is the value an instance of a particular type?
* This version assumes no relationship between the required type and
* the signature of the method that sets it up, for example in
* <code>assertThat($anObject, anInstanceOf('Thing'));</code>
*/
function any($theClass)
{
return \Hamcrest\Core\IsInstanceOf::anInstanceOf($theClass);
}
}
if (!function_exists('not')) { /**
* Matches if value does not match $value.
*/
function not($value)
{
return \Hamcrest\Core\IsNot::not($value);
}
}
if (!function_exists('nullValue')) { /**
* Matches if value is null.
*/
function nullValue()
{
return \Hamcrest\Core\IsNull::nullValue();
}
}
if (!function_exists('notNullValue')) { /**
* Matches if value is not null.
*/
function notNullValue()
{
return \Hamcrest\Core\IsNull::notNullValue();
}
}
if (!function_exists('sameInstance')) { /**
* Creates a new instance of IsSame.
*
* @param mixed $object
* The predicate evaluates to true only when the argument is
* this object.
*
* @return \Hamcrest\Core\IsSame
*/
function sameInstance($object)
{
return \Hamcrest\Core\IsSame::sameInstance($object);
}
}
if (!function_exists('typeOf')) { /**
* Is the value a particular built-in type?
*/
function typeOf($theType)
{
return \Hamcrest\Core\IsTypeOf::typeOf($theType);
}
}
if (!function_exists('set')) { /**
* Matches if value (class, object, or array) has named $property.
*/
function set($property)
{
return \Hamcrest\Core\Set::set($property);
}
}
if (!function_exists('notSet')) { /**
* Matches if value (class, object, or array) does not have named $property.
*/
function notSet($property)
{
return \Hamcrest\Core\Set::notSet($property);
}
}
if (!function_exists('closeTo')) { /**
* Matches if value is a number equal to $value within some range of
* acceptable error $delta.
*/
function closeTo($value, $delta)
{
return \Hamcrest\Number\IsCloseTo::closeTo($value, $delta);
}
}
if (!function_exists('comparesEqualTo')) { /**
* The value is not > $value, nor < $value.
*/
function comparesEqualTo($value)
{
return \Hamcrest\Number\OrderingComparison::comparesEqualTo($value);
}
}
if (!function_exists('greaterThan')) { /**
* The value is > $value.
*/
function greaterThan($value)
{
return \Hamcrest\Number\OrderingComparison::greaterThan($value);
}
}
if (!function_exists('greaterThanOrEqualTo')) { /**
* The value is >= $value.
*/
function greaterThanOrEqualTo($value)
{
return \Hamcrest\Number\OrderingComparison::greaterThanOrEqualTo($value);
}
}
if (!function_exists('atLeast')) { /**
* The value is >= $value.
*/
function atLeast($value)
{
return \Hamcrest\Number\OrderingComparison::greaterThanOrEqualTo($value);
}
}
if (!function_exists('lessThan')) { /**
* The value is < $value.
*/
function lessThan($value)
{
return \Hamcrest\Number\OrderingComparison::lessThan($value);
}
}
if (!function_exists('lessThanOrEqualTo')) { /**
* The value is <= $value.
*/
function lessThanOrEqualTo($value)
{
return \Hamcrest\Number\OrderingComparison::lessThanOrEqualTo($value);
}
}
if (!function_exists('atMost')) { /**
* The value is <= $value.
*/
function atMost($value)
{
return \Hamcrest\Number\OrderingComparison::lessThanOrEqualTo($value);
}
}
if (!function_exists('isEmptyString')) { /**
* Matches if value is a zero-length string.
*/
function isEmptyString()
{
return \Hamcrest\Text\IsEmptyString::isEmptyString();
}
}
if (!function_exists('emptyString')) { /**
* Matches if value is a zero-length string.
*/
function emptyString()
{
return \Hamcrest\Text\IsEmptyString::isEmptyString();
}
}
if (!function_exists('isEmptyOrNullString')) { /**
* Matches if value is null or a zero-length string.
*/
function isEmptyOrNullString()
{
return \Hamcrest\Text\IsEmptyString::isEmptyOrNullString();
}
}
if (!function_exists('nullOrEmptyString')) { /**
* Matches if value is null or a zero-length string.
*/
function nullOrEmptyString()
{
return \Hamcrest\Text\IsEmptyString::isEmptyOrNullString();
}
}
if (!function_exists('isNonEmptyString')) { /**
* Matches if value is a non-zero-length string.
*/
function isNonEmptyString()
{
return \Hamcrest\Text\IsEmptyString::isNonEmptyString();
}
}
if (!function_exists('nonEmptyString')) { /**
* Matches if value is a non-zero-length string.
*/
function nonEmptyString()
{
return \Hamcrest\Text\IsEmptyString::isNonEmptyString();
}
}
if (!function_exists('equalToIgnoringCase')) { /**
* Matches if value is a string equal to $string, regardless of the case.
*/
function equalToIgnoringCase($string)
{
return \Hamcrest\Text\IsEqualIgnoringCase::equalToIgnoringCase($string);
}
}
if (!function_exists('equalToIgnoringWhiteSpace')) { /**
* Matches if value is a string equal to $string, regardless of whitespace.
*/
function equalToIgnoringWhiteSpace($string)
{
return \Hamcrest\Text\IsEqualIgnoringWhiteSpace::equalToIgnoringWhiteSpace($string);
}
}
if (!function_exists('matchesPattern')) { /**
* Matches if value is a string that matches regular expression $pattern.
*/
function matchesPattern($pattern)
{
return \Hamcrest\Text\MatchesPattern::matchesPattern($pattern);
}
}
if (!function_exists('containsString')) { /**
* Matches if value is a string that contains $substring.
*/
function containsString($substring)
{
return \Hamcrest\Text\StringContains::containsString($substring);
}
}
if (!function_exists('containsStringIgnoringCase')) { /**
* Matches if value is a string that contains $substring regardless of the case.
*/
function containsStringIgnoringCase($substring)
{
return \Hamcrest\Text\StringContainsIgnoringCase::containsStringIgnoringCase($substring);
}
}
if (!function_exists('stringContainsInOrder')) { /**
* Matches if value contains $substrings in a constrained order.
*/
function stringContainsInOrder(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Text\StringContainsInOrder', 'stringContainsInOrder'), $args);
}
}
if (!function_exists('endsWith')) { /**
* Matches if value is a string that ends with $substring.
*/
function endsWith($substring)
{
return \Hamcrest\Text\StringEndsWith::endsWith($substring);
}
}
if (!function_exists('startsWith')) { /**
* Matches if value is a string that starts with $substring.
*/
function startsWith($substring)
{
return \Hamcrest\Text\StringStartsWith::startsWith($substring);
}
}
if (!function_exists('arrayValue')) { /**
* Is the value an array?
*/
function arrayValue()
{
return \Hamcrest\Type\IsArray::arrayValue();
}
}
if (!function_exists('booleanValue')) { /**
* Is the value a boolean?
*/
function booleanValue()
{
return \Hamcrest\Type\IsBoolean::booleanValue();
}
}
if (!function_exists('boolValue')) { /**
* Is the value a boolean?
*/
function boolValue()
{
return \Hamcrest\Type\IsBoolean::booleanValue();
}
}
if (!function_exists('callableValue')) { /**
* Is the value callable?
*/
function callableValue()
{
return \Hamcrest\Type\IsCallable::callableValue();
}
}
if (!function_exists('doubleValue')) { /**
* Is the value a float/double?
*/
function doubleValue()
{
return \Hamcrest\Type\IsDouble::doubleValue();
}
}
if (!function_exists('floatValue')) { /**
* Is the value a float/double?
*/
function floatValue()
{
return \Hamcrest\Type\IsDouble::doubleValue();
}
}
if (!function_exists('integerValue')) { /**
* Is the value an integer?
*/
function integerValue()
{
return \Hamcrest\Type\IsInteger::integerValue();
}
}
if (!function_exists('intValue')) { /**
* Is the value an integer?
*/
function intValue()
{
return \Hamcrest\Type\IsInteger::integerValue();
}
}
if (!function_exists('numericValue')) { /**
* Is the value a numeric?
*/
function numericValue()
{
return \Hamcrest\Type\IsNumeric::numericValue();
}
}
if (!function_exists('objectValue')) { /**
* Is the value an object?
*/
function objectValue()
{
return \Hamcrest\Type\IsObject::objectValue();
}
}
if (!function_exists('anObject')) { /**
* Is the value an object?
*/
function anObject()
{
return \Hamcrest\Type\IsObject::objectValue();
}
}
if (!function_exists('resourceValue')) { /**
* Is the value a resource?
*/
function resourceValue()
{
return \Hamcrest\Type\IsResource::resourceValue();
}
}
if (!function_exists('scalarValue')) { /**
* Is the value a scalar (boolean, integer, double, or string)?
*/
function scalarValue()
{
return \Hamcrest\Type\IsScalar::scalarValue();
}
}
if (!function_exists('stringValue')) { /**
* Is the value a string?
*/
function stringValue()
{
return \Hamcrest\Type\IsString::stringValue();
}
}
if (!function_exists('hasXPath')) { /**
* Wraps <code>$matcher</code> with {@link Hamcrest\Core\IsEqual)
* if it's not a matcher and the XPath in <code>count()</code>
* if it's an integer.
*/
function hasXPath($xpath, $matcher = null)
{
return \Hamcrest\Xml\HasXPath::hasXPath($xpath, $matcher);
}
}

View File

@@ -0,0 +1,118 @@
<?php
namespace Hamcrest\Arrays;
/*
Copyright (c) 2009 hamcrest.org
*/
// NOTE: This class is not exactly a direct port of Java's since Java handles
// arrays quite differently than PHP
// TODO: Allow this to take matchers or values within the array
use Hamcrest\Description;
use Hamcrest\TypeSafeMatcher;
use Hamcrest\Util;
/**
* Matcher for array whose elements satisfy a sequence of matchers.
* The array size must equal the number of element matchers.
*/
class IsArray extends TypeSafeMatcher
{
private $_elementMatchers;
public function __construct(array $elementMatchers)
{
parent::__construct(self::TYPE_ARRAY);
Util::checkAllAreMatchers($elementMatchers);
$this->_elementMatchers = $elementMatchers;
}
protected function matchesSafely($array)
{
if (array_keys($array) != array_keys($this->_elementMatchers)) {
return false;
}
/** @var $matcher \Hamcrest\Matcher */
foreach ($this->_elementMatchers as $k => $matcher) {
if (!$matcher->matches($array[$k])) {
return false;
}
}
return true;
}
protected function describeMismatchSafely($actual, Description $mismatchDescription)
{
if (count($actual) != count($this->_elementMatchers)) {
$mismatchDescription->appendText('array length was ' . count($actual));
return;
} elseif (array_keys($actual) != array_keys($this->_elementMatchers)) {
$mismatchDescription->appendText('array keys were ')
->appendValueList(
$this->descriptionStart(),
$this->descriptionSeparator(),
$this->descriptionEnd(),
array_keys($actual)
)
;
return;
}
/** @var $matcher \Hamcrest\Matcher */
foreach ($this->_elementMatchers as $k => $matcher) {
if (!$matcher->matches($actual[$k])) {
$mismatchDescription->appendText('element ')->appendValue($k)
->appendText(' was ')->appendValue($actual[$k]);
return;
}
}
}
public function describeTo(Description $description)
{
$description->appendList(
$this->descriptionStart(),
$this->descriptionSeparator(),
$this->descriptionEnd(),
$this->_elementMatchers
);
}
/**
* Evaluates to true only if each $matcher[$i] is satisfied by $array[$i].
*
* @factory ...
*/
public static function anArray(/* args... */)
{
$args = func_get_args();
return new self(Util::createMatcherArray($args));
}
// -- Protected Methods
protected function descriptionStart()
{
return '[';
}
protected function descriptionSeparator()
{
return ', ';
}
protected function descriptionEnd()
{
return ']';
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Hamcrest\Arrays;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\Matcher;
use Hamcrest\TypeSafeMatcher;
use Hamcrest\Util;
/**
* Matches if an array contains an item satisfying a nested matcher.
*/
class IsArrayContaining extends TypeSafeMatcher
{
private $_elementMatcher;
public function __construct(Matcher $elementMatcher)
{
parent::__construct(self::TYPE_ARRAY);
$this->_elementMatcher = $elementMatcher;
}
protected function matchesSafely($array)
{
foreach ($array as $element) {
if ($this->_elementMatcher->matches($element)) {
return true;
}
}
return false;
}
protected function describeMismatchSafely($array, Description $mismatchDescription)
{
$mismatchDescription->appendText('was ')->appendValue($array);
}
public function describeTo(Description $description)
{
$description
->appendText('an array containing ')
->appendDescriptionOf($this->_elementMatcher)
;
}
/**
* Evaluates to true if any item in an array satisfies the given matcher.
*
* @param mixed $item as a {@link Hamcrest\Matcher} or a value.
*
* @return \Hamcrest\Arrays\IsArrayContaining
* @factory hasValue
*/
public static function hasItemInArray($item)
{
return new self(Util::wrapValueWithIsEqual($item));
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Hamcrest\Arrays;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\TypeSafeDiagnosingMatcher;
use Hamcrest\Util;
/**
* Matches if an array contains a set of items satisfying nested matchers.
*/
class IsArrayContainingInAnyOrder extends TypeSafeDiagnosingMatcher
{
private $_elementMatchers;
public function __construct(array $elementMatchers)
{
parent::__construct(self::TYPE_ARRAY);
Util::checkAllAreMatchers($elementMatchers);
$this->_elementMatchers = $elementMatchers;
}
protected function matchesSafelyWithDiagnosticDescription($array, Description $mismatchDescription)
{
$matching = new MatchingOnce($this->_elementMatchers, $mismatchDescription);
foreach ($array as $element) {
if (!$matching->matches($element)) {
return false;
}
}
return $matching->isFinished($array);
}
public function describeTo(Description $description)
{
$description->appendList('[', ', ', ']', $this->_elementMatchers)
->appendText(' in any order')
;
}
/**
* An array with elements that match the given matchers.
*
* @factory containsInAnyOrder ...
*/
public static function arrayContainingInAnyOrder(/* args... */)
{
$args = func_get_args();
return new self(Util::createMatcherArray($args));
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace Hamcrest\Arrays;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\TypeSafeDiagnosingMatcher;
use Hamcrest\Util;
/**
* Matches if an array contains a set of items satisfying nested matchers.
*/
class IsArrayContainingInOrder extends TypeSafeDiagnosingMatcher
{
private $_elementMatchers;
public function __construct(array $elementMatchers)
{
parent::__construct(self::TYPE_ARRAY);
Util::checkAllAreMatchers($elementMatchers);
$this->_elementMatchers = $elementMatchers;
}
protected function matchesSafelyWithDiagnosticDescription($array, Description $mismatchDescription)
{
$series = new SeriesMatchingOnce($this->_elementMatchers, $mismatchDescription);
foreach ($array as $element) {
if (!$series->matches($element)) {
return false;
}
}
return $series->isFinished();
}
public function describeTo(Description $description)
{
$description->appendList('[', ', ', ']', $this->_elementMatchers);
}
/**
* An array with elements that match the given matchers in the same order.
*
* @factory contains ...
*/
public static function arrayContaining(/* args... */)
{
$args = func_get_args();
return new self(Util::createMatcherArray($args));
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace Hamcrest\Arrays;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\Matcher;
use Hamcrest\TypeSafeMatcher;
use Hamcrest\Util;
/**
* Matches if an array contains the specified key.
*/
class IsArrayContainingKey extends TypeSafeMatcher
{
private $_keyMatcher;
public function __construct(Matcher $keyMatcher)
{
parent::__construct(self::TYPE_ARRAY);
$this->_keyMatcher = $keyMatcher;
}
protected function matchesSafely($array)
{
foreach ($array as $key => $element) {
if ($this->_keyMatcher->matches($key)) {
return true;
}
}
return false;
}
protected function describeMismatchSafely($array, Description $mismatchDescription)
{
//Not using appendValueList() so that keys can be shown
$mismatchDescription->appendText('array was ')
->appendText('[')
;
$loop = false;
foreach ($array as $key => $value) {
if ($loop) {
$mismatchDescription->appendText(', ');
}
$mismatchDescription->appendValue($key)->appendText(' => ')->appendValue($value);
$loop = true;
}
$mismatchDescription->appendText(']');
}
public function describeTo(Description $description)
{
$description
->appendText('array with key ')
->appendDescriptionOf($this->_keyMatcher)
;
}
/**
* Evaluates to true if any key in an array matches the given matcher.
*
* @param mixed $key as a {@link Hamcrest\Matcher} or a value.
*
* @return \Hamcrest\Arrays\IsArrayContainingKey
* @factory hasKey
*/
public static function hasKeyInArray($key)
{
return new self(Util::wrapValueWithIsEqual($key));
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace Hamcrest\Arrays;
/**
* Tests for the presence of both a key and value inside an array.
*/
use Hamcrest\Description;
use Hamcrest\Matcher;
use Hamcrest\TypeSafeMatcher;
use Hamcrest\Util;
/**
* @namespace
*/
class IsArrayContainingKeyValuePair extends TypeSafeMatcher
{
private $_keyMatcher;
private $_valueMatcher;
public function __construct(Matcher $keyMatcher, Matcher $valueMatcher)
{
parent::__construct(self::TYPE_ARRAY);
$this->_keyMatcher = $keyMatcher;
$this->_valueMatcher = $valueMatcher;
}
protected function matchesSafely($array)
{
foreach ($array as $key => $value) {
if ($this->_keyMatcher->matches($key) && $this->_valueMatcher->matches($value)) {
return true;
}
}
return false;
}
protected function describeMismatchSafely($array, Description $mismatchDescription)
{
//Not using appendValueList() so that keys can be shown
$mismatchDescription->appendText('array was ')
->appendText('[')
;
$loop = false;
foreach ($array as $key => $value) {
if ($loop) {
$mismatchDescription->appendText(', ');
}
$mismatchDescription->appendValue($key)->appendText(' => ')->appendValue($value);
$loop = true;
}
$mismatchDescription->appendText(']');
}
public function describeTo(Description $description)
{
$description->appendText('array containing [')
->appendDescriptionOf($this->_keyMatcher)
->appendText(' => ')
->appendDescriptionOf($this->_valueMatcher)
->appendText(']')
;
}
/**
* Test if an array has both an key and value in parity with each other.
*
* @factory hasEntry
*/
public static function hasKeyValuePair($key, $value)
{
return new self(
Util::wrapValueWithIsEqual($key),
Util::wrapValueWithIsEqual($value)
);
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace Hamcrest\Arrays;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Core\DescribedAs;
use Hamcrest\Core\IsNot;
use Hamcrest\FeatureMatcher;
use Hamcrest\Matcher;
use Hamcrest\Util;
/**
* Matches if array size satisfies a nested matcher.
*/
class IsArrayWithSize extends FeatureMatcher
{
public function __construct(Matcher $sizeMatcher)
{
parent::__construct(
self::TYPE_ARRAY,
null,
$sizeMatcher,
'an array with size',
'array size'
);
}
protected function featureValueOf($array)
{
return count($array);
}
/**
* Does array size satisfy a given matcher?
*
* @param \Hamcrest\Matcher|int $size as a {@link Hamcrest\Matcher} or a value.
*
* @return \Hamcrest\Arrays\IsArrayWithSize
* @factory
*/
public static function arrayWithSize($size)
{
return new self(Util::wrapValueWithIsEqual($size));
}
/**
* Matches an empty array.
*
* @factory
*/
public static function emptyArray()
{
return DescribedAs::describedAs(
'an empty array',
self::arrayWithSize(0)
);
}
/**
* Matches an empty array.
*
* @factory
*/
public static function nonEmptyArray()
{
return DescribedAs::describedAs(
'a non-empty array',
self::arrayWithSize(IsNot::not(0))
);
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace Hamcrest\Arrays;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
class MatchingOnce
{
private $_elementMatchers;
private $_mismatchDescription;
public function __construct(array $elementMatchers, Description $mismatchDescription)
{
$this->_elementMatchers = $elementMatchers;
$this->_mismatchDescription = $mismatchDescription;
}
public function matches($item)
{
return $this->_isNotSurplus($item) && $this->_isMatched($item);
}
public function isFinished($items)
{
if (empty($this->_elementMatchers)) {
return true;
}
$this->_mismatchDescription
->appendText('No item matches: ')->appendList('', ', ', '', $this->_elementMatchers)
->appendText(' in ')->appendValueList('[', ', ', ']', $items)
;
return false;
}
// -- Private Methods
private function _isNotSurplus($item)
{
if (empty($this->_elementMatchers)) {
$this->_mismatchDescription->appendText('Not matched: ')->appendValue($item);
return false;
}
return true;
}
private function _isMatched($item)
{
/** @var $matcher \Hamcrest\Matcher */
foreach ($this->_elementMatchers as $i => $matcher) {
if ($matcher->matches($item)) {
unset($this->_elementMatchers[$i]);
return true;
}
}
$this->_mismatchDescription->appendText('Not matched: ')->appendValue($item);
return false;
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace Hamcrest\Arrays;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\Matcher;
class SeriesMatchingOnce
{
private $_elementMatchers;
private $_keys;
private $_mismatchDescription;
private $_nextMatchKey;
public function __construct(array $elementMatchers, Description $mismatchDescription)
{
$this->_elementMatchers = $elementMatchers;
$this->_keys = array_keys($elementMatchers);
$this->_mismatchDescription = $mismatchDescription;
}
public function matches($item)
{
return $this->_isNotSurplus($item) && $this->_isMatched($item);
}
public function isFinished()
{
if (!empty($this->_elementMatchers)) {
$nextMatcher = current($this->_elementMatchers);
$this->_mismatchDescription->appendText('No item matched: ')->appendDescriptionOf($nextMatcher);
return false;
}
return true;
}
// -- Private Methods
private function _isNotSurplus($item)
{
if (empty($this->_elementMatchers)) {
$this->_mismatchDescription->appendText('Not matched: ')->appendValue($item);
return false;
}
return true;
}
private function _isMatched($item)
{
$this->_nextMatchKey = array_shift($this->_keys);
$nextMatcher = array_shift($this->_elementMatchers);
if (!$nextMatcher->matches($item)) {
$this->_describeMismatch($nextMatcher, $item);
return false;
}
return true;
}
private function _describeMismatch(Matcher $matcher, $item)
{
$this->_mismatchDescription->appendText('item with key ' . $this->_nextMatchKey . ': ');
$matcher->describeMismatch($item, $this->_mismatchDescription);
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Hamcrest;
/*
Copyright (c) 2009 hamcrest.org
*/
class AssertionError extends \RuntimeException
{
}

View File

@@ -0,0 +1,132 @@
<?php
namespace Hamcrest;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Internal\SelfDescribingValue;
/**
* A {@link Hamcrest\Description} that is stored as a string.
*/
abstract class BaseDescription implements Description
{
public function appendText($text)
{
$this->append($text);
return $this;
}
public function appendDescriptionOf(SelfDescribing $value)
{
$value->describeTo($this);
return $this;
}
public function appendValue($value)
{
if (is_null($value)) {
$this->append('null');
} elseif (is_string($value)) {
$this->_toPhpSyntax($value);
} elseif (is_float($value)) {
$this->append('<');
$this->append($value);
$this->append('F>');
} elseif (is_bool($value)) {
$this->append('<');
$this->append($value ? 'true' : 'false');
$this->append('>');
} elseif (is_array($value) || $value instanceof \Iterator || $value instanceof \IteratorAggregate) {
$this->appendValueList('[', ', ', ']', $value);
} elseif (is_object($value) && !method_exists($value, '__toString')) {
$this->append('<');
$this->append(get_class($value));
$this->append('>');
} else {
$this->append('<');
$this->append($value);
$this->append('>');
}
return $this;
}
public function appendValueList($start, $separator, $end, $values)
{
$list = array();
foreach ($values as $v) {
$list[] = new SelfDescribingValue($v);
}
$this->appendList($start, $separator, $end, $list);
return $this;
}
public function appendList($start, $separator, $end, $values)
{
$this->append($start);
$separate = false;
foreach ($values as $value) {
/*if (!($value instanceof Hamcrest\SelfDescribing)) {
$value = new Hamcrest\Internal\SelfDescribingValue($value);
}*/
if ($separate) {
$this->append($separator);
}
$this->appendDescriptionOf($value);
$separate = true;
}
$this->append($end);
return $this;
}
// -- Protected Methods
/**
* Append the String <var>$str</var> to the description.
*/
abstract protected function append($str);
// -- Private Methods
private function _toPhpSyntax($value)
{
$str = '"';
for ($i = 0, $len = strlen($value); $i < $len; ++$i) {
switch ($value[$i]) {
case '"':
$str .= '\\"';
break;
case "\t":
$str .= '\\t';
break;
case "\r":
$str .= '\\r';
break;
case "\n":
$str .= '\\n';
break;
default:
$str .= $value[$i];
}
}
$str .= '"';
$this->append($str);
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Hamcrest;
/*
Copyright (c) 2009 hamcrest.org
*/
/**
* BaseClass for all Matcher implementations.
*
* @see Hamcrest\Matcher
*/
abstract class BaseMatcher implements Matcher
{
public function describeMismatch($item, Description $description)
{
$description->appendText('was ')->appendValue($item);
}
public function __toString()
{
return StringDescription::toString($this);
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace Hamcrest\Collection;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\BaseMatcher;
use Hamcrest\Description;
/**
* Matches if traversable is empty or non-empty.
*/
class IsEmptyTraversable extends BaseMatcher
{
private static $_INSTANCE;
private static $_NOT_INSTANCE;
private $_empty;
public function __construct($empty = true)
{
$this->_empty = $empty;
}
public function matches($item)
{
if (!$item instanceof \Traversable) {
return false;
}
foreach ($item as $value) {
return !$this->_empty;
}
return $this->_empty;
}
public function describeTo(Description $description)
{
$description->appendText($this->_empty ? 'an empty traversable' : 'a non-empty traversable');
}
/**
* Returns true if traversable is empty.
*
* @factory
*/
public static function emptyTraversable()
{
if (!self::$_INSTANCE) {
self::$_INSTANCE = new self;
}
return self::$_INSTANCE;
}
/**
* Returns true if traversable is not empty.
*
* @factory
*/
public static function nonEmptyTraversable()
{
if (!self::$_NOT_INSTANCE) {
self::$_NOT_INSTANCE = new self(false);
}
return self::$_NOT_INSTANCE;
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Hamcrest\Collection;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\FeatureMatcher;
use Hamcrest\Matcher;
use Hamcrest\Util;
/**
* Matches if traversable size satisfies a nested matcher.
*/
class IsTraversableWithSize extends FeatureMatcher
{
public function __construct(Matcher $sizeMatcher)
{
parent::__construct(
self::TYPE_OBJECT,
'Traversable',
$sizeMatcher,
'a traversable with size',
'traversable size'
);
}
protected function featureValueOf($actual)
{
$size = 0;
foreach ($actual as $value) {
$size++;
}
return $size;
}
/**
* Does traversable size satisfy a given matcher?
*
* @factory
*/
public static function traversableWithSize($size)
{
return new self(Util::wrapValueWithIsEqual($size));
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\DiagnosingMatcher;
use Hamcrest\Util;
/**
* Calculates the logical conjunction of multiple matchers. Evaluation is
* shortcut, so subsequent matchers are not called if an earlier matcher
* returns <code>false</code>.
*/
class AllOf extends DiagnosingMatcher
{
private $_matchers;
public function __construct(array $matchers)
{
Util::checkAllAreMatchers($matchers);
$this->_matchers = $matchers;
}
public function matchesWithDiagnosticDescription($item, Description $mismatchDescription)
{
/** @var $matcher \Hamcrest\Matcher */
foreach ($this->_matchers as $matcher) {
if (!$matcher->matches($item)) {
$mismatchDescription->appendDescriptionOf($matcher)->appendText(' ');
$matcher->describeMismatch($item, $mismatchDescription);
return false;
}
}
return true;
}
public function describeTo(Description $description)
{
$description->appendList('(', ' and ', ')', $this->_matchers);
}
/**
* Evaluates to true only if ALL of the passed in matchers evaluate to true.
*
* @factory ...
*/
public static function allOf(/* args... */)
{
$args = func_get_args();
return new self(Util::createMatcherArray($args));
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\Util;
/**
* Calculates the logical disjunction of multiple matchers. Evaluation is
* shortcut, so subsequent matchers are not called if an earlier matcher
* returns <code>true</code>.
*/
class AnyOf extends ShortcutCombination
{
public function __construct(array $matchers)
{
parent::__construct($matchers);
}
public function matches($item)
{
return $this->matchesWithShortcut($item, true);
}
public function describeTo(Description $description)
{
$this->describeToWithOperator($description, 'or');
}
/**
* Evaluates to true if ANY of the passed in matchers evaluate to true.
*
* @factory ...
*/
public static function anyOf(/* args... */)
{
$args = func_get_args();
return new self(Util::createMatcherArray($args));
}
/**
* Evaluates to false if ANY of the passed in matchers evaluate to true.
*
* @factory ...
*/
public static function noneOf(/* args... */)
{
$args = func_get_args();
return IsNot::not(
new self(Util::createMatcherArray($args))
);
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\BaseMatcher;
use Hamcrest\Description;
use Hamcrest\Matcher;
class CombinableMatcher extends BaseMatcher
{
private $_matcher;
public function __construct(Matcher $matcher)
{
$this->_matcher = $matcher;
}
public function matches($item)
{
return $this->_matcher->matches($item);
}
public function describeTo(Description $description)
{
$description->appendDescriptionOf($this->_matcher);
}
/** Diversion from Hamcrest-Java... Logical "and" not permitted */
public function andAlso(Matcher $other)
{
return new self(new AllOf($this->_templatedListWith($other)));
}
/** Diversion from Hamcrest-Java... Logical "or" not permitted */
public function orElse(Matcher $other)
{
return new self(new AnyOf($this->_templatedListWith($other)));
}
/**
* This is useful for fluently combining matchers that must both pass.
* For example:
* <pre>
* assertThat($string, both(containsString("a"))->andAlso(containsString("b")));
* </pre>
*
* @factory
*/
public static function both(Matcher $matcher)
{
return new self($matcher);
}
/**
* This is useful for fluently combining matchers where either may pass,
* for example:
* <pre>
* assertThat($string, either(containsString("a"))->orElse(containsString("b")));
* </pre>
*
* @factory
*/
public static function either(Matcher $matcher)
{
return new self($matcher);
}
// -- Private Methods
private function _templatedListWith(Matcher $other)
{
return array($this->_matcher, $other);
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\BaseMatcher;
use Hamcrest\Description;
use Hamcrest\Matcher;
/**
* Provides a custom description to another matcher.
*/
class DescribedAs extends BaseMatcher
{
private $_descriptionTemplate;
private $_matcher;
private $_values;
const ARG_PATTERN = '/%([0-9]+)/';
public function __construct($descriptionTemplate, Matcher $matcher, array $values)
{
$this->_descriptionTemplate = $descriptionTemplate;
$this->_matcher = $matcher;
$this->_values = $values;
}
public function matches($item)
{
return $this->_matcher->matches($item);
}
public function describeTo(Description $description)
{
$textStart = 0;
while (preg_match(self::ARG_PATTERN, $this->_descriptionTemplate, $matches, PREG_OFFSET_CAPTURE, $textStart)) {
$text = $matches[0][0];
$index = $matches[1][0];
$offset = $matches[0][1];
$description->appendText(substr($this->_descriptionTemplate, $textStart, $offset - $textStart));
$description->appendValue($this->_values[$index]);
$textStart = $offset + strlen($text);
}
if ($textStart < strlen($this->_descriptionTemplate)) {
$description->appendText(substr($this->_descriptionTemplate, $textStart));
}
}
/**
* Wraps an existing matcher and overrides the description when it fails.
*
* @factory ...
*/
public static function describedAs(/* $description, Hamcrest\Matcher $matcher, $values... */)
{
$args = func_get_args();
$description = array_shift($args);
$matcher = array_shift($args);
$values = $args;
return new self($description, $matcher, $values);
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\Matcher;
use Hamcrest\TypeSafeDiagnosingMatcher;
class Every extends TypeSafeDiagnosingMatcher
{
private $_matcher;
public function __construct(Matcher $matcher)
{
parent::__construct(self::TYPE_ARRAY);
$this->_matcher = $matcher;
}
protected function matchesSafelyWithDiagnosticDescription($items, Description $mismatchDescription)
{
foreach ($items as $item) {
if (!$this->_matcher->matches($item)) {
$mismatchDescription->appendText('an item ');
$this->_matcher->describeMismatch($item, $mismatchDescription);
return false;
}
}
return true;
}
public function describeTo(Description $description)
{
$description->appendText('every item is ')->appendDescriptionOf($this->_matcher);
}
/**
* @param Matcher $itemMatcher
* A matcher to apply to every element in an array.
*
* @return \Hamcrest\Core\Every
* Evaluates to TRUE for a collection in which every item matches $itemMatcher
*
* @factory
*/
public static function everyItem(Matcher $itemMatcher)
{
return new self($itemMatcher);
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\FeatureMatcher;
use Hamcrest\Matcher;
use Hamcrest\Util;
/**
* Matches if array size satisfies a nested matcher.
*/
class HasToString extends FeatureMatcher
{
public function __construct(Matcher $toStringMatcher)
{
parent::__construct(
self::TYPE_OBJECT,
null,
$toStringMatcher,
'an object with toString()',
'toString()'
);
}
public function matchesSafelyWithDiagnosticDescription($actual, Description $mismatchDescription)
{
if (method_exists($actual, 'toString') || method_exists($actual, '__toString')) {
return parent::matchesSafelyWithDiagnosticDescription($actual, $mismatchDescription);
}
return false;
}
protected function featureValueOf($actual)
{
if (method_exists($actual, 'toString')) {
return $actual->toString();
}
return (string) $actual;
}
/**
* Does array size satisfy a given matcher?
*
* @factory
*/
public static function hasToString($matcher)
{
return new self(Util::wrapValueWithIsEqual($matcher));
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\BaseMatcher;
use Hamcrest\Description;
use Hamcrest\Matcher;
use Hamcrest\Util;
/**
* Decorates another Matcher, retaining the behavior but allowing tests
* to be slightly more expressive.
*
* For example: assertThat($cheese, equalTo($smelly))
* vs. assertThat($cheese, is(equalTo($smelly)))
*/
class Is extends BaseMatcher
{
private $_matcher;
public function __construct(Matcher $matcher)
{
$this->_matcher = $matcher;
}
public function matches($arg)
{
return $this->_matcher->matches($arg);
}
public function describeTo(Description $description)
{
$description->appendText('is ')->appendDescriptionOf($this->_matcher);
}
public function describeMismatch($item, Description $mismatchDescription)
{
$this->_matcher->describeMismatch($item, $mismatchDescription);
}
/**
* Decorates another Matcher, retaining the behavior but allowing tests
* to be slightly more expressive.
*
* For example: assertThat($cheese, equalTo($smelly))
* vs. assertThat($cheese, is(equalTo($smelly)))
*
* @factory
*/
public static function is($value)
{
return new self(Util::wrapValueWithIsEqual($value));
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\BaseMatcher;
use Hamcrest\Description;
/**
* A matcher that always returns <code>true</code>.
*/
class IsAnything extends BaseMatcher
{
private $_message;
public function __construct($message = 'ANYTHING')
{
$this->_message = $message;
}
public function matches($item)
{
return true;
}
public function describeTo(Description $description)
{
$description->appendText($this->_message);
}
/**
* This matcher always evaluates to true.
*
* @param string $description A meaningful string used when describing itself.
*
* @return \Hamcrest\Core\IsAnything
* @factory
*/
public static function anything($description = 'ANYTHING')
{
return new self($description);
}
}

View File

@@ -0,0 +1,93 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\Matcher;
use Hamcrest\TypeSafeMatcher;
use Hamcrest\Util;
/**
* Tests if an array contains values that match one or more Matchers.
*/
class IsCollectionContaining extends TypeSafeMatcher
{
private $_elementMatcher;
public function __construct(Matcher $elementMatcher)
{
parent::__construct(self::TYPE_ARRAY);
$this->_elementMatcher = $elementMatcher;
}
protected function matchesSafely($items)
{
foreach ($items as $item) {
if ($this->_elementMatcher->matches($item)) {
return true;
}
}
return false;
}
protected function describeMismatchSafely($items, Description $mismatchDescription)
{
$mismatchDescription->appendText('was ')->appendValue($items);
}
public function describeTo(Description $description)
{
$description
->appendText('a collection containing ')
->appendDescriptionOf($this->_elementMatcher)
;
}
/**
* Test if the value is an array containing this matcher.
*
* Example:
* <pre>
* assertThat(array('a', 'b'), hasItem(equalTo('b')));
* //Convenience defaults to equalTo()
* assertThat(array('a', 'b'), hasItem('b'));
* </pre>
*
* @factory ...
*/
public static function hasItem()
{
$args = func_get_args();
$firstArg = array_shift($args);
return new self(Util::wrapValueWithIsEqual($firstArg));
}
/**
* Test if the value is an array containing elements that match all of these
* matchers.
*
* Example:
* <pre>
* assertThat(array('a', 'b', 'c'), hasItems(equalTo('a'), equalTo('b')));
* </pre>
*
* @factory ...
*/
public static function hasItems(/* args... */)
{
$args = func_get_args();
$matchers = array();
foreach ($args as $arg) {
$matchers[] = self::hasItem($arg);
}
return AllOf::allOf($matchers);
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\BaseMatcher;
use Hamcrest\Description;
/**
* Is the value equal to another value, as tested by the use of the "=="
* comparison operator?
*/
class IsEqual extends BaseMatcher
{
private $_item;
public function __construct($item)
{
$this->_item = $item;
}
public function matches($arg)
{
return (($arg == $this->_item) && ($this->_item == $arg));
}
public function describeTo(Description $description)
{
$description->appendValue($this->_item);
}
/**
* Is the value equal to another value, as tested by the use of the "=="
* comparison operator?
*
* @factory
*/
public static function equalTo($item)
{
return new self($item);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
/**
* The same as {@link Hamcrest\Core\IsSame} but with slightly different
* semantics.
*/
class IsIdentical extends IsSame
{
private $_value;
public function __construct($value)
{
parent::__construct($value);
$this->_value = $value;
}
public function describeTo(Description $description)
{
$description->appendValue($this->_value);
}
/**
* Tests of the value is identical to $value as tested by the "===" operator.
*
* @factory
*/
public static function identicalTo($value)
{
return new self($value);
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\DiagnosingMatcher;
/**
* Tests whether the value is an instance of a class.
*/
class IsInstanceOf extends DiagnosingMatcher
{
private $_theClass;
/**
* Creates a new instance of IsInstanceOf
*
* @param string $theClass
* The predicate evaluates to true for instances of this class
* or one of its subclasses.
*/
public function __construct($theClass)
{
$this->_theClass = $theClass;
}
protected function matchesWithDiagnosticDescription($item, Description $mismatchDescription)
{
if (!is_object($item)) {
$mismatchDescription->appendText('was ')->appendValue($item);
return false;
}
if (!($item instanceof $this->_theClass)) {
$mismatchDescription->appendText('[' . get_class($item) . '] ')
->appendValue($item);
return false;
}
return true;
}
public function describeTo(Description $description)
{
$description->appendText('an instance of ')
->appendText($this->_theClass)
;
}
/**
* Is the value an instance of a particular type?
* This version assumes no relationship between the required type and
* the signature of the method that sets it up, for example in
* <code>assertThat($anObject, anInstanceOf('Thing'));</code>
*
* @factory any
*/
public static function anInstanceOf($theClass)
{
return new self($theClass);
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\BaseMatcher;
use Hamcrest\Description;
use Hamcrest\Matcher;
use Hamcrest\Util;
/**
* Calculates the logical negation of a matcher.
*/
class IsNot extends BaseMatcher
{
private $_matcher;
public function __construct(Matcher $matcher)
{
$this->_matcher = $matcher;
}
public function matches($arg)
{
return !$this->_matcher->matches($arg);
}
public function describeTo(Description $description)
{
$description->appendText('not ')->appendDescriptionOf($this->_matcher);
}
/**
* Matches if value does not match $value.
*
* @factory
*/
public static function not($value)
{
return new self(Util::wrapValueWithIsEqual($value));
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\BaseMatcher;
use Hamcrest\Description;
/**
* Is the value null?
*/
class IsNull extends BaseMatcher
{
private static $_INSTANCE;
private static $_NOT_INSTANCE;
public function matches($item)
{
return is_null($item);
}
public function describeTo(Description $description)
{
$description->appendText('null');
}
/**
* Matches if value is null.
*
* @factory
*/
public static function nullValue()
{
if (!self::$_INSTANCE) {
self::$_INSTANCE = new self();
}
return self::$_INSTANCE;
}
/**
* Matches if value is not null.
*
* @factory
*/
public static function notNullValue()
{
if (!self::$_NOT_INSTANCE) {
self::$_NOT_INSTANCE = IsNot::not(self::nullValue());
}
return self::$_NOT_INSTANCE;
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\BaseMatcher;
use Hamcrest\Description;
/**
* Is the value the same object as another value?
* In PHP terms, does $a === $b?
*/
class IsSame extends BaseMatcher
{
private $_object;
public function __construct($object)
{
$this->_object = $object;
}
public function matches($object)
{
return ($object === $this->_object) && ($this->_object === $object);
}
public function describeTo(Description $description)
{
$description->appendText('sameInstance(')
->appendValue($this->_object)
->appendText(')')
;
}
/**
* Creates a new instance of IsSame.
*
* @param mixed $object
* The predicate evaluates to true only when the argument is
* this object.
*
* @return \Hamcrest\Core\IsSame
* @factory
*/
public static function sameInstance($object)
{
return new self($object);
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2010 hamcrest.org
*/
use Hamcrest\BaseMatcher;
use Hamcrest\Description;
/**
* Tests whether the value has a built-in type.
*/
class IsTypeOf extends BaseMatcher
{
private $_theType;
/**
* Creates a new instance of IsTypeOf
*
* @param string $theType
* The predicate evaluates to true for values with this built-in type.
*/
public function __construct($theType)
{
$this->_theType = strtolower($theType);
}
public function matches($item)
{
return strtolower(gettype($item)) == $this->_theType;
}
public function describeTo(Description $description)
{
$description->appendText(self::getTypeDescription($this->_theType));
}
public function describeMismatch($item, Description $description)
{
if ($item === null) {
$description->appendText('was null');
} else {
$description->appendText('was ')
->appendText(self::getTypeDescription(strtolower(gettype($item))))
->appendText(' ')
->appendValue($item)
;
}
}
public static function getTypeDescription($type)
{
if ($type == 'null') {
return 'null';
}
return (strpos('aeiou', substr($type, 0, 1)) === false ? 'a ' : 'an ')
. $type;
}
/**
* Is the value a particular built-in type?
*
* @factory
*/
public static function typeOf($theType)
{
return new self($theType);
}
}

View File

@@ -0,0 +1,95 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2010 hamcrest.org
*/
use Hamcrest\BaseMatcher;
use Hamcrest\Description;
/**
* Tests if a value (class, object, or array) has a named property.
*
* For example:
* <pre>
* assertThat(array('a', 'b'), set('b'));
* assertThat($foo, set('bar'));
* assertThat('Server', notSet('defaultPort'));
* </pre>
*
* @todo Replace $property with a matcher and iterate all property names.
*/
class Set extends BaseMatcher
{
private $_property;
private $_not;
public function __construct($property, $not = false)
{
$this->_property = $property;
$this->_not = $not;
}
public function matches($item)
{
if ($item === null) {
return false;
}
$property = $this->_property;
if (is_array($item)) {
$result = isset($item[$property]);
} elseif (is_object($item)) {
$result = isset($item->$property);
} elseif (is_string($item)) {
$result = isset($item::$$property);
} else {
throw new \InvalidArgumentException('Must pass an object, array, or class name');
}
return $this->_not ? !$result : $result;
}
public function describeTo(Description $description)
{
$description->appendText($this->_not ? 'unset property ' : 'set property ')->appendText($this->_property);
}
public function describeMismatch($item, Description $description)
{
$value = '';
if (!$this->_not) {
$description->appendText('was not set');
} else {
$property = $this->_property;
if (is_array($item)) {
$value = $item[$property];
} elseif (is_object($item)) {
$value = $item->$property;
} elseif (is_string($item)) {
$value = $item::$$property;
}
parent::describeMismatch($value, $description);
}
}
/**
* Matches if value (class, object, or array) has named $property.
*
* @factory
*/
public static function set($property)
{
return new self($property);
}
/**
* Matches if value (class, object, or array) does not have named $property.
*
* @factory
*/
public static function notSet($property)
{
return new self($property, true);
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace Hamcrest\Core;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\BaseMatcher;
use Hamcrest\Description;
use Hamcrest\Util;
abstract class ShortcutCombination extends BaseMatcher
{
/**
* @var array<\Hamcrest\Matcher>
*/
private $_matchers;
public function __construct(array $matchers)
{
Util::checkAllAreMatchers($matchers);
$this->_matchers = $matchers;
}
protected function matchesWithShortcut($item, $shortcut)
{
/** @var $matcher \Hamcrest\Matcher */
foreach ($this->_matchers as $matcher) {
if ($matcher->matches($item) == $shortcut) {
return $shortcut;
}
}
return !$shortcut;
}
public function describeToWithOperator(Description $description, $operator)
{
$description->appendList('(', ' ' . $operator . ' ', ')', $this->_matchers);
}
}

View File

@@ -0,0 +1,70 @@
<?php
namespace Hamcrest;
/*
Copyright (c) 2009 hamcrest.org
*/
/**
* A description of a Matcher. A Matcher will describe itself to a description
* which can later be used for reporting.
*
* @see Hamcrest\Matcher::describeTo()
*/
interface Description
{
/**
* Appends some plain text to the description.
*
* @param string $text
*
* @return \Hamcrest\Description
*/
public function appendText($text);
/**
* Appends the description of a {@link Hamcrest\SelfDescribing} value to
* this description.
*
* @param \Hamcrest\SelfDescribing $value
*
* @return \Hamcrest\Description
*/
public function appendDescriptionOf(SelfDescribing $value);
/**
* Appends an arbitary value to the description.
*
* @param mixed $value
*
* @return \Hamcrest\Description
*/
public function appendValue($value);
/**
* Appends a list of values to the description.
*
* @param string $start
* @param string $separator
* @param string $end
* @param array|\IteratorAggregate|\Iterator $values
*
* @return \Hamcrest\Description
*/
public function appendValueList($start, $separator, $end, $values);
/**
* Appends a list of {@link Hamcrest\SelfDescribing} objects to the
* description.
*
* @param string $start
* @param string $separator
* @param string $end
* @param array|\\IteratorAggregate|\\Iterator $values
* must be instances of {@link Hamcrest\SelfDescribing}
*
* @return \Hamcrest\Description
*/
public function appendList($start, $separator, $end, $values);
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Hamcrest;
/*
Copyright (c) 2009 hamcrest.org
*/
/**
* Official documentation for this class is missing.
*/
abstract class DiagnosingMatcher extends BaseMatcher
{
final public function matches($item)
{
return $this->matchesWithDiagnosticDescription($item, new NullDescription());
}
public function describeMismatch($item, Description $mismatchDescription)
{
$this->matchesWithDiagnosticDescription($item, $mismatchDescription);
}
abstract protected function matchesWithDiagnosticDescription($item, Description $mismatchDescription);
}

View File

@@ -0,0 +1,67 @@
<?php
namespace Hamcrest;
/*
Copyright (c) 2009 hamcrest.org
*/
/**
* Supporting class for matching a feature of an object. Implement
* <code>featureValueOf()</code> in a subclass to pull out the feature to be
* matched against.
*/
abstract class FeatureMatcher extends TypeSafeDiagnosingMatcher
{
private $_subMatcher;
private $_featureDescription;
private $_featureName;
/**
* Constructor.
*
* @param string $type
* @param string $subtype
* @param \Hamcrest\Matcher $subMatcher The matcher to apply to the feature
* @param string $featureDescription Descriptive text to use in describeTo
* @param string $featureName Identifying text for mismatch message
*/
public function __construct($type, $subtype, Matcher $subMatcher, $featureDescription, $featureName)
{
parent::__construct($type, $subtype);
$this->_subMatcher = $subMatcher;
$this->_featureDescription = $featureDescription;
$this->_featureName = $featureName;
}
/**
* Implement this to extract the interesting feature.
*
* @param mixed $actual the target object
*
* @return mixed the feature to be matched
*/
abstract protected function featureValueOf($actual);
public function matchesSafelyWithDiagnosticDescription($actual, Description $mismatchDescription)
{
$featureValue = $this->featureValueOf($actual);
if (!$this->_subMatcher->matches($featureValue)) {
$mismatchDescription->appendText($this->_featureName)
->appendText(' was ')->appendValue($featureValue);
return false;
}
return true;
}
final public function describeTo(Description $description)
{
$description->appendText($this->_featureDescription)->appendText(' ')
->appendDescriptionOf($this->_subMatcher)
;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Hamcrest\Internal;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\SelfDescribing;
/**
* A wrapper around any value so that it describes itself.
*/
class SelfDescribingValue implements SelfDescribing
{
private $_value;
public function __construct($value)
{
$this->_value = $value;
}
public function describeTo(Description $description)
{
$description->appendValue($this->_value);
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace Hamcrest;
/*
Copyright (c) 2009 hamcrest.org
*/
/**
* A matcher over acceptable values.
* A matcher is able to describe itself to give feedback when it fails.
* <p/>
* Matcher implementations should <b>NOT directly implement this interface</b>.
* Instead, <b>extend</b> the {@link Hamcrest\BaseMatcher} abstract class,
* which will ensure that the Matcher API can grow to support
* new features and remain compatible with all Matcher implementations.
* <p/>
* For easy access to common Matcher implementations, use the static factory
* methods in {@link Hamcrest\CoreMatchers}.
*
* @see Hamcrest\CoreMatchers
* @see Hamcrest\BaseMatcher
*/
interface Matcher extends SelfDescribing
{
/**
* Evaluates the matcher for argument <var>$item</var>.
*
* @param mixed $item the object against which the matcher is evaluated.
*
* @return boolean <code>true</code> if <var>$item</var> matches,
* otherwise <code>false</code>.
*
* @see Hamcrest\BaseMatcher
*/
public function matches($item);
/**
* Generate a description of why the matcher has not accepted the item.
* The description will be part of a larger description of why a matching
* failed, so it should be concise.
* This method assumes that <code>matches($item)</code> is false, but
* will not check this.
*
* @param mixed $item The item that the Matcher has rejected.
* @param Description $description
* @return
*/
public function describeMismatch($item, Description $description);
}

View File

@@ -0,0 +1,118 @@
<?php
namespace Hamcrest;
/*
Copyright (c) 2009 hamcrest.org
*/
class MatcherAssert
{
/**
* Number of assertions performed.
*
* @var int
*/
private static $_count = 0;
/**
* Make an assertion and throw {@link Hamcrest\AssertionError} if it fails.
*
* The first parameter may optionally be a string identifying the assertion
* to be included in the failure message.
*
* If the third parameter is not a matcher it is passed to
* {@link Hamcrest\Core\IsEqual#equalTo} to create one.
*
* Example:
* <pre>
* // With an identifier
* assertThat("apple flavour", $apple->flavour(), equalTo("tasty"));
* // Without an identifier
* assertThat($apple->flavour(), equalTo("tasty"));
* // Evaluating a boolean expression
* assertThat("some error", $a > $b);
* assertThat($a > $b);
* </pre>
*/
public static function assertThat(/* $args ... */)
{
$args = func_get_args();
switch (count($args)) {
case 1:
self::$_count++;
if (!$args[0]) {
throw new AssertionError();
}
break;
case 2:
self::$_count++;
if ($args[1] instanceof Matcher) {
self::doAssert('', $args[0], $args[1]);
} elseif (!$args[1]) {
throw new AssertionError($args[0]);
}
break;
case 3:
self::$_count++;
self::doAssert(
$args[0],
$args[1],
Util::wrapValueWithIsEqual($args[2])
);
break;
default:
throw new \InvalidArgumentException('assertThat() requires one to three arguments');
}
}
/**
* Returns the number of assertions performed.
*
* @return int
*/
public static function getCount()
{
return self::$_count;
}
/**
* Resets the number of assertions performed to zero.
*/
public static function resetCount()
{
self::$_count = 0;
}
/**
* Performs the actual assertion logic.
*
* If <code>$matcher</code> doesn't match <code>$actual</code>,
* throws a {@link Hamcrest\AssertionError} with a description
* of the failure along with the optional <code>$identifier</code>.
*
* @param string $identifier added to the message upon failure
* @param mixed $actual value to compare against <code>$matcher</code>
* @param \Hamcrest\Matcher $matcher applied to <code>$actual</code>
* @throws AssertionError
*/
private static function doAssert($identifier, $actual, Matcher $matcher)
{
if (!$matcher->matches($actual)) {
$description = new StringDescription();
if (!empty($identifier)) {
$description->appendText($identifier . PHP_EOL);
}
$description->appendText('Expected: ')
->appendDescriptionOf($matcher)
->appendText(PHP_EOL . ' but: ');
$matcher->describeMismatch($actual, $description);
throw new AssertionError((string) $description);
}
}
}

View File

@@ -0,0 +1,713 @@
<?php
/*
Copyright (c) 2009-2010 hamcrest.org
*/
// This file is generated from the static method @factory doctags.
namespace Hamcrest;
/**
* A series of static factories for all hamcrest matchers.
*/
class Matchers
{
/**
* Evaluates to true only if each $matcher[$i] is satisfied by $array[$i].
*/
public static function anArray(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Arrays\IsArray', 'anArray'), $args);
}
/**
* Evaluates to true if any item in an array satisfies the given matcher.
*
* @param mixed $item as a {@link Hamcrest\Matcher} or a value.
*
* @return \Hamcrest\Arrays\IsArrayContaining
*/
public static function hasItemInArray($item)
{
return \Hamcrest\Arrays\IsArrayContaining::hasItemInArray($item);
}
/**
* Evaluates to true if any item in an array satisfies the given matcher.
*
* @param mixed $item as a {@link Hamcrest\Matcher} or a value.
*
* @return \Hamcrest\Arrays\IsArrayContaining
*/
public static function hasValue($item)
{
return \Hamcrest\Arrays\IsArrayContaining::hasItemInArray($item);
}
/**
* An array with elements that match the given matchers.
*/
public static function arrayContainingInAnyOrder(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Arrays\IsArrayContainingInAnyOrder', 'arrayContainingInAnyOrder'), $args);
}
/**
* An array with elements that match the given matchers.
*/
public static function containsInAnyOrder(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Arrays\IsArrayContainingInAnyOrder', 'arrayContainingInAnyOrder'), $args);
}
/**
* An array with elements that match the given matchers in the same order.
*/
public static function arrayContaining(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Arrays\IsArrayContainingInOrder', 'arrayContaining'), $args);
}
/**
* An array with elements that match the given matchers in the same order.
*/
public static function contains(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Arrays\IsArrayContainingInOrder', 'arrayContaining'), $args);
}
/**
* Evaluates to true if any key in an array matches the given matcher.
*
* @param mixed $key as a {@link Hamcrest\Matcher} or a value.
*
* @return \Hamcrest\Arrays\IsArrayContainingKey
*/
public static function hasKeyInArray($key)
{
return \Hamcrest\Arrays\IsArrayContainingKey::hasKeyInArray($key);
}
/**
* Evaluates to true if any key in an array matches the given matcher.
*
* @param mixed $key as a {@link Hamcrest\Matcher} or a value.
*
* @return \Hamcrest\Arrays\IsArrayContainingKey
*/
public static function hasKey($key)
{
return \Hamcrest\Arrays\IsArrayContainingKey::hasKeyInArray($key);
}
/**
* Test if an array has both an key and value in parity with each other.
*/
public static function hasKeyValuePair($key, $value)
{
return \Hamcrest\Arrays\IsArrayContainingKeyValuePair::hasKeyValuePair($key, $value);
}
/**
* Test if an array has both an key and value in parity with each other.
*/
public static function hasEntry($key, $value)
{
return \Hamcrest\Arrays\IsArrayContainingKeyValuePair::hasKeyValuePair($key, $value);
}
/**
* Does array size satisfy a given matcher?
*
* @param \Hamcrest\Matcher|int $size as a {@link Hamcrest\Matcher} or a value.
*
* @return \Hamcrest\Arrays\IsArrayWithSize
*/
public static function arrayWithSize($size)
{
return \Hamcrest\Arrays\IsArrayWithSize::arrayWithSize($size);
}
/**
* Matches an empty array.
*/
public static function emptyArray()
{
return \Hamcrest\Arrays\IsArrayWithSize::emptyArray();
}
/**
* Matches an empty array.
*/
public static function nonEmptyArray()
{
return \Hamcrest\Arrays\IsArrayWithSize::nonEmptyArray();
}
/**
* Returns true if traversable is empty.
*/
public static function emptyTraversable()
{
return \Hamcrest\Collection\IsEmptyTraversable::emptyTraversable();
}
/**
* Returns true if traversable is not empty.
*/
public static function nonEmptyTraversable()
{
return \Hamcrest\Collection\IsEmptyTraversable::nonEmptyTraversable();
}
/**
* Does traversable size satisfy a given matcher?
*/
public static function traversableWithSize($size)
{
return \Hamcrest\Collection\IsTraversableWithSize::traversableWithSize($size);
}
/**
* Evaluates to true only if ALL of the passed in matchers evaluate to true.
*/
public static function allOf(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Core\AllOf', 'allOf'), $args);
}
/**
* Evaluates to true if ANY of the passed in matchers evaluate to true.
*/
public static function anyOf(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Core\AnyOf', 'anyOf'), $args);
}
/**
* Evaluates to false if ANY of the passed in matchers evaluate to true.
*/
public static function noneOf(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Core\AnyOf', 'noneOf'), $args);
}
/**
* This is useful for fluently combining matchers that must both pass.
* For example:
* <pre>
* assertThat($string, both(containsString("a"))->andAlso(containsString("b")));
* </pre>
*/
public static function both(\Hamcrest\Matcher $matcher)
{
return \Hamcrest\Core\CombinableMatcher::both($matcher);
}
/**
* This is useful for fluently combining matchers where either may pass,
* for example:
* <pre>
* assertThat($string, either(containsString("a"))->orElse(containsString("b")));
* </pre>
*/
public static function either(\Hamcrest\Matcher $matcher)
{
return \Hamcrest\Core\CombinableMatcher::either($matcher);
}
/**
* Wraps an existing matcher and overrides the description when it fails.
*/
public static function describedAs(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Core\DescribedAs', 'describedAs'), $args);
}
/**
* @param Matcher $itemMatcher
* A matcher to apply to every element in an array.
*
* @return \Hamcrest\Core\Every
* Evaluates to TRUE for a collection in which every item matches $itemMatcher
*/
public static function everyItem(\Hamcrest\Matcher $itemMatcher)
{
return \Hamcrest\Core\Every::everyItem($itemMatcher);
}
/**
* Does array size satisfy a given matcher?
*/
public static function hasToString($matcher)
{
return \Hamcrest\Core\HasToString::hasToString($matcher);
}
/**
* Decorates another Matcher, retaining the behavior but allowing tests
* to be slightly more expressive.
*
* For example: assertThat($cheese, equalTo($smelly))
* vs. assertThat($cheese, is(equalTo($smelly)))
*/
public static function is($value)
{
return \Hamcrest\Core\Is::is($value);
}
/**
* This matcher always evaluates to true.
*
* @param string $description A meaningful string used when describing itself.
*
* @return \Hamcrest\Core\IsAnything
*/
public static function anything($description = 'ANYTHING')
{
return \Hamcrest\Core\IsAnything::anything($description);
}
/**
* Test if the value is an array containing this matcher.
*
* Example:
* <pre>
* assertThat(array('a', 'b'), hasItem(equalTo('b')));
* //Convenience defaults to equalTo()
* assertThat(array('a', 'b'), hasItem('b'));
* </pre>
*/
public static function hasItem(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Core\IsCollectionContaining', 'hasItem'), $args);
}
/**
* Test if the value is an array containing elements that match all of these
* matchers.
*
* Example:
* <pre>
* assertThat(array('a', 'b', 'c'), hasItems(equalTo('a'), equalTo('b')));
* </pre>
*/
public static function hasItems(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Core\IsCollectionContaining', 'hasItems'), $args);
}
/**
* Is the value equal to another value, as tested by the use of the "=="
* comparison operator?
*/
public static function equalTo($item)
{
return \Hamcrest\Core\IsEqual::equalTo($item);
}
/**
* Tests of the value is identical to $value as tested by the "===" operator.
*/
public static function identicalTo($value)
{
return \Hamcrest\Core\IsIdentical::identicalTo($value);
}
/**
* Is the value an instance of a particular type?
* This version assumes no relationship between the required type and
* the signature of the method that sets it up, for example in
* <code>assertThat($anObject, anInstanceOf('Thing'));</code>
*/
public static function anInstanceOf($theClass)
{
return \Hamcrest\Core\IsInstanceOf::anInstanceOf($theClass);
}
/**
* Is the value an instance of a particular type?
* This version assumes no relationship between the required type and
* the signature of the method that sets it up, for example in
* <code>assertThat($anObject, anInstanceOf('Thing'));</code>
*/
public static function any($theClass)
{
return \Hamcrest\Core\IsInstanceOf::anInstanceOf($theClass);
}
/**
* Matches if value does not match $value.
*/
public static function not($value)
{
return \Hamcrest\Core\IsNot::not($value);
}
/**
* Matches if value is null.
*/
public static function nullValue()
{
return \Hamcrest\Core\IsNull::nullValue();
}
/**
* Matches if value is not null.
*/
public static function notNullValue()
{
return \Hamcrest\Core\IsNull::notNullValue();
}
/**
* Creates a new instance of IsSame.
*
* @param mixed $object
* The predicate evaluates to true only when the argument is
* this object.
*
* @return \Hamcrest\Core\IsSame
*/
public static function sameInstance($object)
{
return \Hamcrest\Core\IsSame::sameInstance($object);
}
/**
* Is the value a particular built-in type?
*/
public static function typeOf($theType)
{
return \Hamcrest\Core\IsTypeOf::typeOf($theType);
}
/**
* Matches if value (class, object, or array) has named $property.
*/
public static function set($property)
{
return \Hamcrest\Core\Set::set($property);
}
/**
* Matches if value (class, object, or array) does not have named $property.
*/
public static function notSet($property)
{
return \Hamcrest\Core\Set::notSet($property);
}
/**
* Matches if value is a number equal to $value within some range of
* acceptable error $delta.
*/
public static function closeTo($value, $delta)
{
return \Hamcrest\Number\IsCloseTo::closeTo($value, $delta);
}
/**
* The value is not > $value, nor < $value.
*/
public static function comparesEqualTo($value)
{
return \Hamcrest\Number\OrderingComparison::comparesEqualTo($value);
}
/**
* The value is > $value.
*/
public static function greaterThan($value)
{
return \Hamcrest\Number\OrderingComparison::greaterThan($value);
}
/**
* The value is >= $value.
*/
public static function greaterThanOrEqualTo($value)
{
return \Hamcrest\Number\OrderingComparison::greaterThanOrEqualTo($value);
}
/**
* The value is >= $value.
*/
public static function atLeast($value)
{
return \Hamcrest\Number\OrderingComparison::greaterThanOrEqualTo($value);
}
/**
* The value is < $value.
*/
public static function lessThan($value)
{
return \Hamcrest\Number\OrderingComparison::lessThan($value);
}
/**
* The value is <= $value.
*/
public static function lessThanOrEqualTo($value)
{
return \Hamcrest\Number\OrderingComparison::lessThanOrEqualTo($value);
}
/**
* The value is <= $value.
*/
public static function atMost($value)
{
return \Hamcrest\Number\OrderingComparison::lessThanOrEqualTo($value);
}
/**
* Matches if value is a zero-length string.
*/
public static function isEmptyString()
{
return \Hamcrest\Text\IsEmptyString::isEmptyString();
}
/**
* Matches if value is a zero-length string.
*/
public static function emptyString()
{
return \Hamcrest\Text\IsEmptyString::isEmptyString();
}
/**
* Matches if value is null or a zero-length string.
*/
public static function isEmptyOrNullString()
{
return \Hamcrest\Text\IsEmptyString::isEmptyOrNullString();
}
/**
* Matches if value is null or a zero-length string.
*/
public static function nullOrEmptyString()
{
return \Hamcrest\Text\IsEmptyString::isEmptyOrNullString();
}
/**
* Matches if value is a non-zero-length string.
*/
public static function isNonEmptyString()
{
return \Hamcrest\Text\IsEmptyString::isNonEmptyString();
}
/**
* Matches if value is a non-zero-length string.
*/
public static function nonEmptyString()
{
return \Hamcrest\Text\IsEmptyString::isNonEmptyString();
}
/**
* Matches if value is a string equal to $string, regardless of the case.
*/
public static function equalToIgnoringCase($string)
{
return \Hamcrest\Text\IsEqualIgnoringCase::equalToIgnoringCase($string);
}
/**
* Matches if value is a string equal to $string, regardless of whitespace.
*/
public static function equalToIgnoringWhiteSpace($string)
{
return \Hamcrest\Text\IsEqualIgnoringWhiteSpace::equalToIgnoringWhiteSpace($string);
}
/**
* Matches if value is a string that matches regular expression $pattern.
*/
public static function matchesPattern($pattern)
{
return \Hamcrest\Text\MatchesPattern::matchesPattern($pattern);
}
/**
* Matches if value is a string that contains $substring.
*/
public static function containsString($substring)
{
return \Hamcrest\Text\StringContains::containsString($substring);
}
/**
* Matches if value is a string that contains $substring regardless of the case.
*/
public static function containsStringIgnoringCase($substring)
{
return \Hamcrest\Text\StringContainsIgnoringCase::containsStringIgnoringCase($substring);
}
/**
* Matches if value contains $substrings in a constrained order.
*/
public static function stringContainsInOrder(/* args... */)
{
$args = func_get_args();
return call_user_func_array(array('\Hamcrest\Text\StringContainsInOrder', 'stringContainsInOrder'), $args);
}
/**
* Matches if value is a string that ends with $substring.
*/
public static function endsWith($substring)
{
return \Hamcrest\Text\StringEndsWith::endsWith($substring);
}
/**
* Matches if value is a string that starts with $substring.
*/
public static function startsWith($substring)
{
return \Hamcrest\Text\StringStartsWith::startsWith($substring);
}
/**
* Is the value an array?
*/
public static function arrayValue()
{
return \Hamcrest\Type\IsArray::arrayValue();
}
/**
* Is the value a boolean?
*/
public static function booleanValue()
{
return \Hamcrest\Type\IsBoolean::booleanValue();
}
/**
* Is the value a boolean?
*/
public static function boolValue()
{
return \Hamcrest\Type\IsBoolean::booleanValue();
}
/**
* Is the value callable?
*/
public static function callableValue()
{
return \Hamcrest\Type\IsCallable::callableValue();
}
/**
* Is the value a float/double?
*/
public static function doubleValue()
{
return \Hamcrest\Type\IsDouble::doubleValue();
}
/**
* Is the value a float/double?
*/
public static function floatValue()
{
return \Hamcrest\Type\IsDouble::doubleValue();
}
/**
* Is the value an integer?
*/
public static function integerValue()
{
return \Hamcrest\Type\IsInteger::integerValue();
}
/**
* Is the value an integer?
*/
public static function intValue()
{
return \Hamcrest\Type\IsInteger::integerValue();
}
/**
* Is the value a numeric?
*/
public static function numericValue()
{
return \Hamcrest\Type\IsNumeric::numericValue();
}
/**
* Is the value an object?
*/
public static function objectValue()
{
return \Hamcrest\Type\IsObject::objectValue();
}
/**
* Is the value an object?
*/
public static function anObject()
{
return \Hamcrest\Type\IsObject::objectValue();
}
/**
* Is the value a resource?
*/
public static function resourceValue()
{
return \Hamcrest\Type\IsResource::resourceValue();
}
/**
* Is the value a scalar (boolean, integer, double, or string)?
*/
public static function scalarValue()
{
return \Hamcrest\Type\IsScalar::scalarValue();
}
/**
* Is the value a string?
*/
public static function stringValue()
{
return \Hamcrest\Type\IsString::stringValue();
}
/**
* Wraps <code>$matcher</code> with {@link Hamcrest\Core\IsEqual)
* if it's not a matcher and the XPath in <code>count()</code>
* if it's an integer.
*/
public static function hasXPath($xpath, $matcher = null)
{
return \Hamcrest\Xml\HasXPath::hasXPath($xpath, $matcher);
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace Hamcrest;
/*
Copyright (c) 2009 hamcrest.org
*/
/**
* Null implementation of {@link Hamcrest\Description}.
*/
class NullDescription implements Description
{
public function appendText($text)
{
return $this;
}
public function appendDescriptionOf(SelfDescribing $value)
{
return $this;
}
public function appendValue($value)
{
return $this;
}
public function appendValueList($start, $separator, $end, $values)
{
return $this;
}
public function appendList($start, $separator, $end, $values)
{
return $this;
}
public function __toString()
{
return '';
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace Hamcrest\Number;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\TypeSafeMatcher;
/**
* Is the value a number equal to a value within some range of
* acceptable error?
*/
class IsCloseTo extends TypeSafeMatcher
{
private $_value;
private $_delta;
public function __construct($value, $delta)
{
parent::__construct(self::TYPE_NUMERIC);
$this->_value = $value;
$this->_delta = $delta;
}
protected function matchesSafely($item)
{
return $this->_actualDelta($item) <= 0.0;
}
protected function describeMismatchSafely($item, Description $mismatchDescription)
{
$mismatchDescription->appendValue($item)
->appendText(' differed by ')
->appendValue($this->_actualDelta($item))
;
}
public function describeTo(Description $description)
{
$description->appendText('a numeric value within ')
->appendValue($this->_delta)
->appendText(' of ')
->appendValue($this->_value)
;
}
/**
* Matches if value is a number equal to $value within some range of
* acceptable error $delta.
*
* @factory
*/
public static function closeTo($value, $delta)
{
return new self($value, $delta);
}
// -- Private Methods
private function _actualDelta($item)
{
return (abs(($item - $this->_value)) - $this->_delta);
}
}

View File

@@ -0,0 +1,132 @@
<?php
namespace Hamcrest\Number;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\TypeSafeMatcher;
class OrderingComparison extends TypeSafeMatcher
{
private $_value;
private $_minCompare;
private $_maxCompare;
public function __construct($value, $minCompare, $maxCompare)
{
parent::__construct(self::TYPE_NUMERIC);
$this->_value = $value;
$this->_minCompare = $minCompare;
$this->_maxCompare = $maxCompare;
}
protected function matchesSafely($other)
{
$compare = $this->_compare($this->_value, $other);
return ($this->_minCompare <= $compare) && ($compare <= $this->_maxCompare);
}
protected function describeMismatchSafely($item, Description $mismatchDescription)
{
$mismatchDescription
->appendValue($item)->appendText(' was ')
->appendText($this->_comparison($this->_compare($this->_value, $item)))
->appendText(' ')->appendValue($this->_value)
;
}
public function describeTo(Description $description)
{
$description->appendText('a value ')
->appendText($this->_comparison($this->_minCompare))
;
if ($this->_minCompare != $this->_maxCompare) {
$description->appendText(' or ')
->appendText($this->_comparison($this->_maxCompare))
;
}
$description->appendText(' ')->appendValue($this->_value);
}
/**
* The value is not > $value, nor < $value.
*
* @factory
*/
public static function comparesEqualTo($value)
{
return new self($value, 0, 0);
}
/**
* The value is > $value.
*
* @factory
*/
public static function greaterThan($value)
{
return new self($value, -1, -1);
}
/**
* The value is >= $value.
*
* @factory atLeast
*/
public static function greaterThanOrEqualTo($value)
{
return new self($value, -1, 0);
}
/**
* The value is < $value.
*
* @factory
*/
public static function lessThan($value)
{
return new self($value, 1, 1);
}
/**
* The value is <= $value.
*
* @factory atMost
*/
public static function lessThanOrEqualTo($value)
{
return new self($value, 0, 1);
}
// -- Private Methods
private function _compare($left, $right)
{
$a = $left;
$b = $right;
if ($a < $b) {
return -1;
} elseif ($a == $b) {
return 0;
} else {
return 1;
}
}
private function _comparison($compare)
{
if ($compare > 0) {
return 'less than';
} elseif ($compare == 0) {
return 'equal to';
} else {
return 'greater than';
}
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Hamcrest;
/*
Copyright (c) 2009 hamcrest.org
*/
/**
* The ability of an object to describe itself.
*/
interface SelfDescribing
{
/**
* Generates a description of the object. The description may be part
* of a description of a larger object of which this is just a component,
* so it should be worded appropriately.
*
* @param \Hamcrest\Description $description
* The description to be built or appended to.
*/
public function describeTo(Description $description);
}

View File

@@ -0,0 +1,57 @@
<?php
namespace Hamcrest;
/*
Copyright (c) 2009 hamcrest.org
*/
/**
* A {@link Hamcrest\Description} that is stored as a string.
*/
class StringDescription extends BaseDescription
{
private $_out;
public function __construct($out = '')
{
$this->_out = (string) $out;
}
public function __toString()
{
return $this->_out;
}
/**
* Return the description of a {@link Hamcrest\SelfDescribing} object as a
* String.
*
* @param \Hamcrest\SelfDescribing $selfDescribing
* The object to be described.
*
* @return string
* The description of the object.
*/
public static function toString(SelfDescribing $selfDescribing)
{
$self = new self();
return (string) $self->appendDescriptionOf($selfDescribing);
}
/**
* Alias for {@link toString()}.
*/
public static function asString(SelfDescribing $selfDescribing)
{
return self::toString($selfDescribing);
}
// -- Protected Methods
protected function append($str)
{
$this->_out .= $str;
}
}

View File

@@ -0,0 +1,85 @@
<?php
namespace Hamcrest\Text;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\BaseMatcher;
use Hamcrest\Core\AnyOf;
use Hamcrest\Core\IsNull;
use Hamcrest\Description;
/**
* Matches empty Strings (and null).
*/
class IsEmptyString extends BaseMatcher
{
private static $_INSTANCE;
private static $_NULL_OR_EMPTY_INSTANCE;
private static $_NOT_INSTANCE;
private $_empty;
public function __construct($empty = true)
{
$this->_empty = $empty;
}
public function matches($item)
{
return $this->_empty
? ($item === '')
: is_string($item) && $item !== '';
}
public function describeTo(Description $description)
{
$description->appendText($this->_empty ? 'an empty string' : 'a non-empty string');
}
/**
* Matches if value is a zero-length string.
*
* @factory emptyString
*/
public static function isEmptyString()
{
if (!self::$_INSTANCE) {
self::$_INSTANCE = new self(true);
}
return self::$_INSTANCE;
}
/**
* Matches if value is null or a zero-length string.
*
* @factory nullOrEmptyString
*/
public static function isEmptyOrNullString()
{
if (!self::$_NULL_OR_EMPTY_INSTANCE) {
self::$_NULL_OR_EMPTY_INSTANCE = AnyOf::anyOf(
IsNull::nullvalue(),
self::isEmptyString()
);
}
return self::$_NULL_OR_EMPTY_INSTANCE;
}
/**
* Matches if value is a non-zero-length string.
*
* @factory nonEmptyString
*/
public static function isNonEmptyString()
{
if (!self::$_NOT_INSTANCE) {
self::$_NOT_INSTANCE = new self(false);
}
return self::$_NOT_INSTANCE;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Hamcrest\Text;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\TypeSafeMatcher;
/**
* Tests if a string is equal to another string, regardless of the case.
*/
class IsEqualIgnoringCase extends TypeSafeMatcher
{
private $_string;
public function __construct($string)
{
parent::__construct(self::TYPE_STRING);
$this->_string = $string;
}
protected function matchesSafely($item)
{
return strtolower($this->_string) === strtolower($item);
}
protected function describeMismatchSafely($item, Description $mismatchDescription)
{
$mismatchDescription->appendText('was ')->appendText($item);
}
public function describeTo(Description $description)
{
$description->appendText('equalToIgnoringCase(')
->appendValue($this->_string)
->appendText(')')
;
}
/**
* Matches if value is a string equal to $string, regardless of the case.
*
* @factory
*/
public static function equalToIgnoringCase($string)
{
return new self($string);
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace Hamcrest\Text;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\TypeSafeMatcher;
/**
* Tests if a string is equal to another string, ignoring any changes in
* whitespace.
*/
class IsEqualIgnoringWhiteSpace extends TypeSafeMatcher
{
private $_string;
public function __construct($string)
{
parent::__construct(self::TYPE_STRING);
$this->_string = $string;
}
protected function matchesSafely($item)
{
return (strtolower($this->_stripSpace($item))
=== strtolower($this->_stripSpace($this->_string)));
}
protected function describeMismatchSafely($item, Description $mismatchDescription)
{
$mismatchDescription->appendText('was ')->appendText($item);
}
public function describeTo(Description $description)
{
$description->appendText('equalToIgnoringWhiteSpace(')
->appendValue($this->_string)
->appendText(')')
;
}
/**
* Matches if value is a string equal to $string, regardless of whitespace.
*
* @factory
*/
public static function equalToIgnoringWhiteSpace($string)
{
return new self($string);
}
// -- Private Methods
private function _stripSpace($string)
{
$parts = preg_split("/[\r\n\t ]+/", $string);
foreach ($parts as $i => $part) {
$parts[$i] = trim($part, " \r\n\t");
}
return trim(implode(' ', $parts), " \r\n\t");
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Hamcrest\Text;
/*
Copyright (c) 2010 hamcrest.org
*/
/**
* Tests if the argument is a string that matches a regular expression.
*/
class MatchesPattern extends SubstringMatcher
{
public function __construct($pattern)
{
parent::__construct($pattern);
}
/**
* Matches if value is a string that matches regular expression $pattern.
*
* @factory
*/
public static function matchesPattern($pattern)
{
return new self($pattern);
}
// -- Protected Methods
protected function evalSubstringOf($item)
{
return preg_match($this->_substring, (string) $item) >= 1;
}
protected function relationship()
{
return 'matching';
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Hamcrest\Text;
/*
Copyright (c) 2009 hamcrest.org
*/
/**
* Tests if the argument is a string that contains a substring.
*/
class StringContains extends SubstringMatcher
{
public function __construct($substring)
{
parent::__construct($substring);
}
public function ignoringCase()
{
return new StringContainsIgnoringCase($this->_substring);
}
/**
* Matches if value is a string that contains $substring.
*
* @factory
*/
public static function containsString($substring)
{
return new self($substring);
}
// -- Protected Methods
protected function evalSubstringOf($item)
{
return (false !== strpos((string) $item, $this->_substring));
}
protected function relationship()
{
return 'containing';
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Hamcrest\Text;
/*
Copyright (c) 2010 hamcrest.org
*/
/**
* Tests if the argument is a string that contains a substring ignoring case.
*/
class StringContainsIgnoringCase extends SubstringMatcher
{
public function __construct($substring)
{
parent::__construct($substring);
}
/**
* Matches if value is a string that contains $substring regardless of the case.
*
* @factory
*/
public static function containsStringIgnoringCase($substring)
{
return new self($substring);
}
// -- Protected Methods
protected function evalSubstringOf($item)
{
return (false !== stripos((string) $item, $this->_substring));
}
protected function relationship()
{
return 'containing in any case';
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace Hamcrest\Text;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\TypeSafeMatcher;
/**
* Tests if the value contains a series of substrings in a constrained order.
*/
class StringContainsInOrder extends TypeSafeMatcher
{
private $_substrings;
public function __construct(array $substrings)
{
parent::__construct(self::TYPE_STRING);
$this->_substrings = $substrings;
}
protected function matchesSafely($item)
{
$fromIndex = 0;
foreach ($this->_substrings as $substring) {
if (false === $fromIndex = strpos($item, $substring, $fromIndex)) {
return false;
}
}
return true;
}
protected function describeMismatchSafely($item, Description $mismatchDescription)
{
$mismatchDescription->appendText('was ')->appendText($item);
}
public function describeTo(Description $description)
{
$description->appendText('a string containing ')
->appendValueList('', ', ', '', $this->_substrings)
->appendText(' in order')
;
}
/**
* Matches if value contains $substrings in a constrained order.
*
* @factory ...
*/
public static function stringContainsInOrder(/* args... */)
{
$args = func_get_args();
if (isset($args[0]) && is_array($args[0])) {
$args = $args[0];
}
return new self($args);
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Hamcrest\Text;
/*
Copyright (c) 2009 hamcrest.org
*/
/**
* Tests if the argument is a string that ends with a substring.
*/
class StringEndsWith extends SubstringMatcher
{
public function __construct($substring)
{
parent::__construct($substring);
}
/**
* Matches if value is a string that ends with $substring.
*
* @factory
*/
public static function endsWith($substring)
{
return new self($substring);
}
// -- Protected Methods
protected function evalSubstringOf($string)
{
return (substr($string, (-1 * strlen($this->_substring))) === $this->_substring);
}
protected function relationship()
{
return 'ending with';
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Hamcrest\Text;
/*
Copyright (c) 2009 hamcrest.org
*/
/**
* Tests if the argument is a string that contains a substring.
*/
class StringStartsWith extends SubstringMatcher
{
public function __construct($substring)
{
parent::__construct($substring);
}
/**
* Matches if value is a string that starts with $substring.
*
* @factory
*/
public static function startsWith($substring)
{
return new self($substring);
}
// -- Protected Methods
protected function evalSubstringOf($string)
{
return (substr($string, 0, strlen($this->_substring)) === $this->_substring);
}
protected function relationship()
{
return 'starting with';
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Hamcrest\Text;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Description;
use Hamcrest\TypeSafeMatcher;
abstract class SubstringMatcher extends TypeSafeMatcher
{
protected $_substring;
public function __construct($substring)
{
parent::__construct(self::TYPE_STRING);
$this->_substring = $substring;
}
protected function matchesSafely($item)
{
return $this->evalSubstringOf($item);
}
protected function describeMismatchSafely($item, Description $mismatchDescription)
{
$mismatchDescription->appendText('was "')->appendText($item)->appendText('"');
}
public function describeTo(Description $description)
{
$description->appendText('a string ')
->appendText($this->relationship())
->appendText(' ')
->appendValue($this->_substring)
;
}
abstract protected function evalSubstringOf($string);
abstract protected function relationship();
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Hamcrest\Type;
/*
Copyright (c) 2010 hamcrest.org
*/
use Hamcrest\Core\IsTypeOf;
/**
* Tests whether the value is an array.
*/
class IsArray extends IsTypeOf
{
/**
* Creates a new instance of IsArray
*/
public function __construct()
{
parent::__construct('array');
}
/**
* Is the value an array?
*
* @factory
*/
public static function arrayValue()
{
return new self;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Hamcrest\Type;
/*
Copyright (c) 2010 hamcrest.org
*/
use Hamcrest\Core\IsTypeOf;
/**
* Tests whether the value is a boolean.
*/
class IsBoolean extends IsTypeOf
{
/**
* Creates a new instance of IsBoolean
*/
public function __construct()
{
parent::__construct('boolean');
}
/**
* Is the value a boolean?
*
* @factory boolValue
*/
public static function booleanValue()
{
return new self;
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Hamcrest\Type;
/*
Copyright (c) 2010 hamcrest.org
*/
use Hamcrest\Core\IsTypeOf;
/**
* Tests whether the value is callable.
*/
class IsCallable extends IsTypeOf
{
/**
* Creates a new instance of IsCallable
*/
public function __construct()
{
parent::__construct('callable');
}
public function matches($item)
{
return is_callable($item);
}
/**
* Is the value callable?
*
* @factory
*/
public static function callableValue()
{
return new self;
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Hamcrest\Type;
/*
Copyright (c) 2010 hamcrest.org
*/
use Hamcrest\Core\IsTypeOf;
/**
* Tests whether the value is a float/double.
*
* PHP returns "double" for values of type "float".
*/
class IsDouble extends IsTypeOf
{
/**
* Creates a new instance of IsDouble
*/
public function __construct()
{
parent::__construct('double');
}
/**
* Is the value a float/double?
*
* @factory floatValue
*/
public static function doubleValue()
{
return new self;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Hamcrest\Type;
/*
Copyright (c) 2010 hamcrest.org
*/
use Hamcrest\Core\IsTypeOf;
/**
* Tests whether the value is an integer.
*/
class IsInteger extends IsTypeOf
{
/**
* Creates a new instance of IsInteger
*/
public function __construct()
{
parent::__construct('integer');
}
/**
* Is the value an integer?
*
* @factory intValue
*/
public static function integerValue()
{
return new self;
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Hamcrest\Type;
/*
Copyright (c) 2010 hamcrest.org
*/
use Hamcrest\Core\IsTypeOf;
/**
* Tests whether the value is numeric.
*/
class IsNumeric extends IsTypeOf
{
public function __construct()
{
parent::__construct('number');
}
public function matches($item)
{
return is_numeric($item);
}
/**
* Is the value a numeric?
*
* @factory
*/
public static function numericValue()
{
return new self;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Hamcrest\Type;
/*
Copyright (c) 2010 hamcrest.org
*/
use Hamcrest\Core\IsTypeOf;
/**
* Tests whether the value is an object.
*/
class IsObject extends IsTypeOf
{
/**
* Creates a new instance of IsObject
*/
public function __construct()
{
parent::__construct('object');
}
/**
* Is the value an object?
*
* @factory anObject
*/
public static function objectValue()
{
return new self;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Hamcrest\Type;
/*
Copyright (c) 2010 hamcrest.org
*/
use Hamcrest\Core\IsTypeOf;
/**
* Tests whether the value is a resource.
*/
class IsResource extends IsTypeOf
{
/**
* Creates a new instance of IsResource
*/
public function __construct()
{
parent::__construct('resource');
}
/**
* Is the value a resource?
*
* @factory
*/
public static function resourceValue()
{
return new self;
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Hamcrest\Type;
/*
Copyright (c) 2010 hamcrest.org
*/
use Hamcrest\Core\IsTypeOf;
/**
* Tests whether the value is a scalar (boolean, integer, double, or string).
*/
class IsScalar extends IsTypeOf
{
public function __construct()
{
parent::__construct('scalar');
}
public function matches($item)
{
return is_scalar($item);
}
/**
* Is the value a scalar (boolean, integer, double, or string)?
*
* @factory
*/
public static function scalarValue()
{
return new self;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Hamcrest\Type;
/*
Copyright (c) 2010 hamcrest.org
*/
use Hamcrest\Core\IsTypeOf;
/**
* Tests whether the value is a string.
*/
class IsString extends IsTypeOf
{
/**
* Creates a new instance of IsString
*/
public function __construct()
{
parent::__construct('string');
}
/**
* Is the value a string?
*
* @factory
*/
public static function stringValue()
{
return new self;
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Hamcrest;
/**
* Convenient base class for Matchers that require a value of a specific type.
* This simply checks the type and then casts.
*/
abstract class TypeSafeDiagnosingMatcher extends TypeSafeMatcher
{
final public function matchesSafely($item)
{
return $this->matchesSafelyWithDiagnosticDescription($item, new NullDescription());
}
final public function describeMismatchSafely($item, Description $mismatchDescription)
{
$this->matchesSafelyWithDiagnosticDescription($item, $mismatchDescription);
}
// -- Protected Methods
/**
* Subclasses should implement these. The item will already have been checked for
* the specific type.
*/
abstract protected function matchesSafelyWithDiagnosticDescription($item, Description $mismatchDescription);
}

View File

@@ -0,0 +1,107 @@
<?php
namespace Hamcrest;
/**
* Convenient base class for Matchers that require a value of a specific type.
* This simply checks the type.
*
* While it may seem a useless exercise to have this in PHP, objects cannot
* be cast to certain data types such as numerics (or even strings if
* __toString() has not be defined).
*/
abstract class TypeSafeMatcher extends BaseMatcher
{
/* Types that PHP can compare against */
const TYPE_ANY = 0;
const TYPE_STRING = 1;
const TYPE_NUMERIC = 2;
const TYPE_ARRAY = 3;
const TYPE_OBJECT = 4;
const TYPE_RESOURCE = 5;
const TYPE_BOOLEAN = 6;
/**
* The type that is required for a safe comparison
*
* @var int
*/
private $_expectedType;
/**
* The subtype (e.g. class for objects) that is required
*
* @var string
*/
private $_expectedSubtype;
public function __construct($expectedType, $expectedSubtype = null)
{
$this->_expectedType = $expectedType;
$this->_expectedSubtype = $expectedSubtype;
}
final public function matches($item)
{
return $this->_isSafeType($item) && $this->matchesSafely($item);
}
final public function describeMismatch($item, Description $mismatchDescription)
{
if (!$this->_isSafeType($item)) {
parent::describeMismatch($item, $mismatchDescription);
} else {
$this->describeMismatchSafely($item, $mismatchDescription);
}
}
// -- Protected Methods
/**
* The item will already have been checked for the specific type and subtype.
*/
abstract protected function matchesSafely($item);
/**
* The item will already have been checked for the specific type and subtype.
*/
abstract protected function describeMismatchSafely($item, Description $mismatchDescription);
// -- Private Methods
private function _isSafeType($value)
{
switch ($this->_expectedType) {
case self::TYPE_ANY:
return true;
case self::TYPE_STRING:
return is_string($value) || is_numeric($value);
case self::TYPE_NUMERIC:
return is_numeric($value) || is_string($value);
case self::TYPE_ARRAY:
return is_array($value);
case self::TYPE_OBJECT:
return is_object($value)
&& ($this->_expectedSubtype === null
|| $value instanceof $this->_expectedSubtype);
case self::TYPE_RESOURCE:
return is_resource($value)
&& ($this->_expectedSubtype === null
|| get_resource_type($value) == $this->_expectedSubtype);
case self::TYPE_BOOLEAN:
return true;
default:
return true;
}
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace Hamcrest;
/*
Copyright (c) 2012 hamcrest.org
*/
/**
* Contains utility methods for handling Hamcrest matchers.
*
* @see Hamcrest\Matcher
*/
class Util
{
/**
* Wraps the item with an IsEqual matcher if it isn't a matcher already.
*
* @param mixed $item matcher or any value
* @return \Hamcrest\Matcher
*/
public static function wrapValueWithIsEqual($item)
{
return ($item instanceof Matcher)
? $item
: Core\IsEqual::equalTo($item)
;
}
/**
* Throws an exception if any item in $matchers is not a Hamcrest\Matcher.
*
* @param array $matchers expected to contain only matchers
* @throws \InvalidArgumentException if any item is not a matcher
*/
public static function checkAllAreMatchers(array $matchers)
{
foreach ($matchers as $m) {
if (!($m instanceof Matcher)) {
throw new \InvalidArgumentException(
'Each argument or element must be a Hamcrest matcher'
);
}
}
}
/**
* Returns a copy of $items where each non-Matcher item is replaced by
* a Hamcrest\Core\IsEqual matcher for the item. If the first and only item
* is an array, it is used as the $items array to support the old style
* of passing an array as the sole argument to a matcher.
*
* @param array $items contains items and matchers
* @return array<Matchers> all items are
*/
public static function createMatcherArray(array $items)
{
//Extract single array item
if (count($items) == 1 && is_array($items[0])) {
$items = $items[0];
}
//Replace non-matchers
foreach ($items as &$item) {
if (!($item instanceof Matcher)) {
$item = Core\IsEqual::equalTo($item);
}
}
return $items;
}
}

View File

@@ -0,0 +1,195 @@
<?php
namespace Hamcrest\Xml;
/*
Copyright (c) 2009 hamcrest.org
*/
use Hamcrest\Core\IsEqual;
use Hamcrest\Description;
use Hamcrest\DiagnosingMatcher;
use Hamcrest\Matcher;
/**
* Matches if XPath applied to XML/HTML/XHTML document either
* evaluates to result matching the matcher or returns at least
* one node, matching the matcher if present.
*/
class HasXPath extends DiagnosingMatcher
{
/**
* XPath to apply to the DOM.
*
* @var string
*/
private $_xpath;
/**
* Optional matcher to apply to the XPath expression result
* or the content of the returned nodes.
*
* @var Matcher
*/
private $_matcher;
public function __construct($xpath, Matcher $matcher = null)
{
$this->_xpath = $xpath;
$this->_matcher = $matcher;
}
/**
* Matches if the XPath matches against the DOM node and the matcher.
*
* @param string|\DOMNode $actual
* @param Description $mismatchDescription
* @return bool
*/
protected function matchesWithDiagnosticDescription($actual, Description $mismatchDescription)
{
if (is_string($actual)) {
$actual = $this->createDocument($actual);
} elseif (!$actual instanceof \DOMNode) {
$mismatchDescription->appendText('was ')->appendValue($actual);
return false;
}
$result = $this->evaluate($actual);
if ($result instanceof \DOMNodeList) {
return $this->matchesContent($result, $mismatchDescription);
} else {
return $this->matchesExpression($result, $mismatchDescription);
}
}
/**
* Creates and returns a <code>DOMDocument</code> from the given
* XML or HTML string.
*
* @param string $text
* @return \DOMDocument built from <code>$text</code>
* @throws \InvalidArgumentException if the document is not valid
*/
protected function createDocument($text)
{
$document = new \DOMDocument();
if (preg_match('/^\s*<\?xml/', $text)) {
if (!@$document->loadXML($text)) {
throw new \InvalidArgumentException('Must pass a valid XML document');
}
} else {
if (!@$document->loadHTML($text)) {
throw new \InvalidArgumentException('Must pass a valid HTML or XHTML document');
}
}
return $document;
}
/**
* Applies the configured XPath to the DOM node and returns either
* the result if it's an expression or the node list if it's a query.
*
* @param \DOMNode $node context from which to issue query
* @return mixed result of expression or DOMNodeList from query
*/
protected function evaluate(\DOMNode $node)
{
if ($node instanceof \DOMDocument) {
$xpathDocument = new \DOMXPath($node);
return $xpathDocument->evaluate($this->_xpath);
} else {
$xpathDocument = new \DOMXPath($node->ownerDocument);
return $xpathDocument->evaluate($this->_xpath, $node);
}
}
/**
* Matches if the list of nodes is not empty and the content of at least
* one node matches the configured matcher, if supplied.
*
* @param \DOMNodeList $nodes selected by the XPath query
* @param Description $mismatchDescription
* @return bool
*/
protected function matchesContent(\DOMNodeList $nodes, Description $mismatchDescription)
{
if ($nodes->length == 0) {
$mismatchDescription->appendText('XPath returned no results');
} elseif ($this->_matcher === null) {
return true;
} else {
foreach ($nodes as $node) {
if ($this->_matcher->matches($node->textContent)) {
return true;
}
}
$content = array();
foreach ($nodes as $node) {
$content[] = $node->textContent;
}
$mismatchDescription->appendText('XPath returned ')
->appendValue($content);
}
return false;
}
/**
* Matches if the result of the XPath expression matches the configured
* matcher or evaluates to <code>true</code> if there is none.
*
* @param mixed $result result of the XPath expression
* @param Description $mismatchDescription
* @return bool
*/
protected function matchesExpression($result, Description $mismatchDescription)
{
if ($this->_matcher === null) {
if ($result) {
return true;
}
$mismatchDescription->appendText('XPath expression result was ')
->appendValue($result);
} else {
if ($this->_matcher->matches($result)) {
return true;
}
$mismatchDescription->appendText('XPath expression result ');
$this->_matcher->describeMismatch($result, $mismatchDescription);
}
return false;
}
public function describeTo(Description $description)
{
$description->appendText('XML or HTML document with XPath "')
->appendText($this->_xpath)
->appendText('"');
if ($this->_matcher !== null) {
$description->appendText(' ');
$this->_matcher->describeTo($description);
}
}
/**
* Wraps <code>$matcher</code> with {@link Hamcrest\Core\IsEqual)
* if it's not a matcher and the XPath in <code>count()</code>
* if it's an integer.
*
* @factory
*/
public static function hasXPath($xpath, $matcher = null)
{
if ($matcher === null || $matcher instanceof Matcher) {
return new self($xpath, $matcher);
} elseif (is_int($matcher) && strpos($xpath, 'count(') !== 0) {
$xpath = 'count(' . $xpath . ')';
}
return new self($xpath, IsEqual::equalTo($matcher));
}
}