updated backend
This commit is contained in:
parent
1fea0f4fe7
commit
11521c2339
3459 changed files with 72735 additions and 168535 deletions
25
pfosten/vendor/phpspec/prophecy/CHANGES.md
vendored
25
pfosten/vendor/phpspec/prophecy/CHANGES.md
vendored
|
|
@ -1,3 +1,28 @@
|
|||
1.10.1 / 2019/12/22
|
||||
===================
|
||||
|
||||
* [fixed] identical callables no longer match as arguments (@ciaranmcnulty)
|
||||
|
||||
1.10.0 / 2019/12/17
|
||||
===================
|
||||
|
||||
* [added] shouldHaveBeenCalled evaluation happens later so un-stubbed calls don't throw (@elvetemedve)
|
||||
* [added] methods can now be doubled case-insensitively to match PHP semantics (@michalbundyra)
|
||||
* [fixed] reduced memory usage by optimising CachedDoubler (@DonCallisto)
|
||||
* [fixed] removed fatal error nesting level when comparing large objects (@scroach)
|
||||
|
||||
1.9.0 / 2019/10/03
|
||||
==================
|
||||
|
||||
* [added] Add willYield feature to Method Prophecy(@tkotosz)
|
||||
* [fixed] Allow `MethodProphecy::willThrow()` to accept Throwable as string (@timoschinkel )
|
||||
* [fixed] Allow new version of phpdocumentor/reflection-docblock (@ricpelo)
|
||||
|
||||
1.8.1 / 2019/06/13
|
||||
==================
|
||||
|
||||
* [fixed] Don't try to patch final constructors (@NiR)
|
||||
|
||||
1.8.0 / 2018/08/05
|
||||
==================
|
||||
|
||||
|
|
|
|||
15
pfosten/vendor/phpspec/prophecy/README.md
vendored
15
pfosten/vendor/phpspec/prophecy/README.md
vendored
|
|
@ -12,7 +12,7 @@ enough to be used inside any testing framework out there with minimal effort.
|
|||
```php
|
||||
<?php
|
||||
|
||||
class UserTest extends PHPUnit_Framework_TestCase
|
||||
class UserTest extends PHPUnit\Framework\TestCase
|
||||
{
|
||||
private $prophet;
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ class UserTest extends PHPUnit_Framework_TestCase
|
|||
$this->assertEquals('hashed_pass', $user->getPassword());
|
||||
}
|
||||
|
||||
protected function setup()
|
||||
protected function setUp()
|
||||
{
|
||||
$this->prophet = new \Prophecy\Prophet;
|
||||
}
|
||||
|
|
@ -206,6 +206,17 @@ $user->setName('everzet')->will(function ($args) use ($user) {
|
|||
And now it doesn't matter how many times or in which order your methods are called.
|
||||
What matters is their behaviors and how well you faked it.
|
||||
|
||||
Note: If the method is called several times, you can use the following syntax to return different
|
||||
values for each call:
|
||||
|
||||
```php
|
||||
$prophecy->read('123')->willReturn(1, 2, 3);
|
||||
```
|
||||
|
||||
This feature is actually not recommended for most cases. Relying on the order of
|
||||
calls for the same arguments tends to make test fragile, as adding one more call
|
||||
can break everything.
|
||||
|
||||
#### Arguments wildcarding
|
||||
|
||||
The previous example is awesome (at least I hope it is for you), but that's not
|
||||
|
|
|
|||
12
pfosten/vendor/phpspec/prophecy/composer.json
vendored
12
pfosten/vendor/phpspec/prophecy/composer.json
vendored
|
|
@ -19,20 +19,20 @@
|
|||
|
||||
"require": {
|
||||
"php": "^5.3|^7.0",
|
||||
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
|
||||
"sebastian/comparator": "^1.1|^2.0|^3.0",
|
||||
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
|
||||
"sebastian/comparator": "^1.2.3|^2.0|^3.0",
|
||||
"doctrine/instantiator": "^1.0.2",
|
||||
"sebastian/recursion-context": "^1.0|^2.0|^3.0"
|
||||
},
|
||||
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "^2.5|^3.2",
|
||||
"phpspec/phpspec": "^2.5 || ^3.2",
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
|
||||
},
|
||||
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Prophecy\\": "src/"
|
||||
"psr-4": {
|
||||
"Prophecy\\": "src/Prophecy"
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.8.x-dev"
|
||||
"dev-master": "1.10.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@ class ExactValueToken implements TokenInterface
|
|||
try {
|
||||
$comparator->assertEquals($argument, $this->value);
|
||||
return 10;
|
||||
} catch (ComparisonFailure $failure) {}
|
||||
} catch (ComparisonFailure $failure) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If either one is an object it should be castable to a string
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@
|
|||
namespace Prophecy\Call;
|
||||
|
||||
use Prophecy\Exception\Prophecy\MethodProphecyException;
|
||||
use Prophecy\Prophecy\MethodProphecy;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Prophecy\Argument\ArgumentsWildcard;
|
||||
use Prophecy\Util\StringUtil;
|
||||
use Prophecy\Exception\Call\UnexpectedCallException;
|
||||
use SplObjectStorage;
|
||||
|
||||
/**
|
||||
* Calls receiver & manager.
|
||||
|
|
@ -32,6 +32,11 @@ class CallCenter
|
|||
*/
|
||||
private $recordedCalls = array();
|
||||
|
||||
/**
|
||||
* @var SplObjectStorage
|
||||
*/
|
||||
private $unexpectedCalls;
|
||||
|
||||
/**
|
||||
* Initializes call center.
|
||||
*
|
||||
|
|
@ -40,6 +45,7 @@ class CallCenter
|
|||
public function __construct(StringUtil $util = null)
|
||||
{
|
||||
$this->util = $util ?: new StringUtil;
|
||||
$this->unexpectedCalls = new SplObjectStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -74,23 +80,21 @@ class CallCenter
|
|||
}
|
||||
|
||||
// If no method prophecies defined, then it's a dummy, so we'll just return null
|
||||
if ('__destruct' === $methodName || 0 == count($prophecy->getMethodProphecies())) {
|
||||
if ('__destruct' === strtolower($methodName) || 0 == count($prophecy->getMethodProphecies())) {
|
||||
$this->recordedCalls[] = new Call($methodName, $arguments, null, null, $file, $line);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// There are method prophecies, so it's a fake/stub. Searching prophecy for this call
|
||||
$matches = array();
|
||||
foreach ($prophecy->getMethodProphecies($methodName) as $methodProphecy) {
|
||||
if (0 < $score = $methodProphecy->getArgumentsWildcard()->scoreArguments($arguments)) {
|
||||
$matches[] = array($score, $methodProphecy);
|
||||
}
|
||||
}
|
||||
$matches = $this->findMethodProphecies($prophecy, $methodName, $arguments);
|
||||
|
||||
// If fake/stub doesn't have method prophecy for this call - throw exception
|
||||
if (!count($matches)) {
|
||||
throw $this->createUnexpectedCallException($prophecy, $methodName, $arguments);
|
||||
$this->unexpectedCalls->attach(new Call($methodName, $arguments, null, null, $file, $line), $prophecy);
|
||||
$this->recordedCalls[] = new Call($methodName, $arguments, null, null, $file, $line);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Sort matches by their score value
|
||||
|
|
@ -138,15 +142,33 @@ class CallCenter
|
|||
*/
|
||||
public function findCalls($methodName, ArgumentsWildcard $wildcard)
|
||||
{
|
||||
$methodName = strtolower($methodName);
|
||||
|
||||
return array_values(
|
||||
array_filter($this->recordedCalls, function (Call $call) use ($methodName, $wildcard) {
|
||||
return $methodName === $call->getMethodName()
|
||||
return $methodName === strtolower($call->getMethodName())
|
||||
&& 0 < $call->getScore($wildcard)
|
||||
;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws UnexpectedCallException
|
||||
*/
|
||||
public function checkUnexpectedCalls()
|
||||
{
|
||||
/** @var Call $call */
|
||||
foreach ($this->unexpectedCalls as $call) {
|
||||
$prophecy = $this->unexpectedCalls[$call];
|
||||
|
||||
// If fake/stub doesn't have method prophecy for this call - throw exception
|
||||
if (!count($this->findMethodProphecies($prophecy, $call->getMethodName(), $call->getArguments()))) {
|
||||
throw $this->createUnexpectedCallException($prophecy, $call->getMethodName(), $call->getArguments());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function createUnexpectedCallException(ObjectProphecy $prophecy, $methodName,
|
||||
array $arguments)
|
||||
{
|
||||
|
|
@ -194,28 +216,6 @@ class CallCenter
|
|||
);
|
||||
}
|
||||
|
||||
private function formatExceptionMessage(MethodProphecy $methodProphecy)
|
||||
{
|
||||
return sprintf(
|
||||
" - %s(\n".
|
||||
"%s\n".
|
||||
" )",
|
||||
$methodProphecy->getMethodName(),
|
||||
implode(
|
||||
",\n",
|
||||
$this->indentArguments(
|
||||
array_map(
|
||||
function ($token) {
|
||||
return (string) $token;
|
||||
},
|
||||
$methodProphecy->getArgumentsWildcard()->getTokens()
|
||||
),
|
||||
$indentationLength
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function indentArguments(array $arguments, $indentationLength)
|
||||
{
|
||||
return preg_replace_callback(
|
||||
|
|
@ -226,4 +226,23 @@ class CallCenter
|
|||
$arguments
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ObjectProphecy $prophecy
|
||||
* @param string $methodName
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function findMethodProphecies(ObjectProphecy $prophecy, $methodName, array $arguments)
|
||||
{
|
||||
$matches = array();
|
||||
foreach ($prophecy->getMethodProphecies($methodName) as $methodProphecy) {
|
||||
if (0 < $score = $methodProphecy->getArgumentsWildcard()->scoreArguments($arguments)) {
|
||||
$matches[] = array($score, $methodProphecy);
|
||||
}
|
||||
}
|
||||
|
||||
return $matches;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,16 +27,18 @@ final class ClosureComparator extends Comparator
|
|||
&& is_object($actual) && $actual instanceof \Closure;
|
||||
}
|
||||
|
||||
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
|
||||
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
|
||||
{
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
// we don't need a diff
|
||||
'',
|
||||
'',
|
||||
false,
|
||||
'all closures are born different'
|
||||
);
|
||||
if ($expected !== $actual) {
|
||||
throw new ComparisonFailure(
|
||||
$expected,
|
||||
$actual,
|
||||
// we don't need a diff
|
||||
'',
|
||||
'',
|
||||
false,
|
||||
'all closures are different if not identical'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,17 +21,7 @@ use ReflectionClass;
|
|||
*/
|
||||
class CachedDoubler extends Doubler
|
||||
{
|
||||
private $classes = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function registerClassPatch(ClassPatch\ClassPatchInterface $patch)
|
||||
{
|
||||
$this->classes[] = array();
|
||||
|
||||
parent::registerClassPatch($patch);
|
||||
}
|
||||
private static $classes = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
@ -39,11 +29,11 @@ class CachedDoubler extends Doubler
|
|||
protected function createDoubleClass(ReflectionClass $class = null, array $interfaces)
|
||||
{
|
||||
$classId = $this->generateClassId($class, $interfaces);
|
||||
if (isset($this->classes[$classId])) {
|
||||
return $this->classes[$classId];
|
||||
if (isset(self::$classes[$classId])) {
|
||||
return self::$classes[$classId];
|
||||
}
|
||||
|
||||
return $this->classes[$classId] = parent::createDoubleClass($class, $interfaces);
|
||||
return self::$classes[$classId] = parent::createDoubleClass($class, $interfaces);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -61,8 +51,16 @@ class CachedDoubler extends Doubler
|
|||
foreach ($interfaces as $interface) {
|
||||
$parts[] = $interface->getName();
|
||||
}
|
||||
foreach ($this->getClassPatches() as $patch) {
|
||||
$parts[] = get_class($patch);
|
||||
}
|
||||
sort($parts);
|
||||
|
||||
return md5(implode('', $parts));
|
||||
}
|
||||
|
||||
public function resetCache()
|
||||
{
|
||||
self::$classes = array();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@ class DisableConstructorPatch implements ClassPatchInterface
|
|||
*/
|
||||
public function apply(ClassNode $node)
|
||||
{
|
||||
if (!$node->isExtendable('__construct')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$node->hasMethod('__construct')) {
|
||||
$node->addMethod(new MethodNode('__construct', ''));
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class ProphecySubjectPatch implements ClassPatchInterface
|
|||
public function apply(ClassNode $node)
|
||||
{
|
||||
$node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface');
|
||||
$node->addProperty('objectProphecy', 'private');
|
||||
$node->addProperty('objectProphecyClosure', 'private');
|
||||
|
||||
foreach ($node->getMethods() as $name => $method) {
|
||||
if ('__construct' === strtolower($name)) {
|
||||
|
|
@ -65,10 +65,10 @@ class ProphecySubjectPatch implements ClassPatchInterface
|
|||
$prophecyArgument = new ArgumentNode('prophecy');
|
||||
$prophecyArgument->setTypeHint('Prophecy\Prophecy\ProphecyInterface');
|
||||
$prophecySetter->addArgument($prophecyArgument);
|
||||
$prophecySetter->setCode('$this->objectProphecy = $prophecy;');
|
||||
$prophecySetter->setCode('$this->objectProphecyClosure = function () use ($prophecy) { return $prophecy; };');
|
||||
|
||||
$prophecyGetter = new MethodNode('getProphecy');
|
||||
$prophecyGetter->setCode('return $this->objectProphecy;');
|
||||
$prophecyGetter->setCode('return call_user_func($this->objectProphecyClosure);');
|
||||
|
||||
if ($node->hasMethod('__call')) {
|
||||
$__call = $node->getMethod('__call');
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ class ClassMirror
|
|||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '7.0', '>=') && $method->hasReturnType()) {
|
||||
$returnType = (string) $method->getReturnType();
|
||||
$returnType = PHP_VERSION_ID >= 70100 ? $method->getReturnType()->getName() : (string) $method->getReturnType();
|
||||
$returnTypeLower = strtolower($returnType);
|
||||
|
||||
if ('self' === $returnTypeLower) {
|
||||
|
|
@ -231,7 +231,7 @@ class ClassMirror
|
|||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '7.0', '>=') && true === $parameter->hasType()) {
|
||||
return (string) $parameter->getType();
|
||||
return PHP_VERSION_ID >= 70100 ? $parameter->getType()->getName() : (string) $parameter->getType();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class ThrowPromise implements PromiseInterface
|
|||
public function __construct($exception)
|
||||
{
|
||||
if (is_string($exception)) {
|
||||
if (!class_exists($exception) || !$this->isAValidThrowable($exception)) {
|
||||
if ((!class_exists($exception) && !interface_exists($exception)) || !$this->isAValidThrowable($exception)) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Exception / Throwable class or instance expected as argument to ThrowPromise, but got %s.',
|
||||
$exception
|
||||
|
|
@ -94,6 +94,7 @@ class ThrowPromise implements PromiseInterface
|
|||
*/
|
||||
private function isAValidThrowable($exception)
|
||||
{
|
||||
return is_a($exception, 'Exception', true) || is_subclass_of($exception, 'Throwable', true);
|
||||
return is_a($exception, 'Exception', true)
|
||||
|| is_a($exception, 'Throwable', true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class MethodProphecy
|
|||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '7.0', '>=') && true === $reflectedMethod->hasReturnType()) {
|
||||
$type = (string) $reflectedMethod->getReturnType();
|
||||
$type = PHP_VERSION_ID >= 70100 ? $reflectedMethod->getReturnType()->getName() : (string) $reflectedMethod->getReturnType();
|
||||
|
||||
if ('void' === $type) {
|
||||
$this->voidReturnType = true;
|
||||
|
|
@ -180,6 +180,40 @@ class MethodProphecy
|
|||
return $this->will(new Promise\ReturnPromise(func_get_args()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $items
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \Prophecy\Exception\InvalidArgumentException
|
||||
*/
|
||||
public function willYield($items)
|
||||
{
|
||||
if ($this->voidReturnType) {
|
||||
throw new MethodProphecyException(
|
||||
"The method \"$this->methodName\" has a void return type, and so cannot yield anything",
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
if (!is_array($items)) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Expected array, but got %s.',
|
||||
gettype($items)
|
||||
));
|
||||
}
|
||||
|
||||
// Remove eval() when minimum version >=5.5
|
||||
/** @var callable $generator */
|
||||
$generator = eval('return function() use ($items) {
|
||||
foreach ($items as $key => $value) {
|
||||
yield $key => $value;
|
||||
}
|
||||
};');
|
||||
|
||||
return $this->will($generator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets return argument promise to the prophecy.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ class ObjectProphecy implements ProphecyInterface
|
|||
), $methodProphecy);
|
||||
}
|
||||
|
||||
$methodName = $methodProphecy->getMethodName();
|
||||
$methodName = strtolower($methodProphecy->getMethodName());
|
||||
|
||||
if (!isset($this->methodProphecies[$methodName])) {
|
||||
$this->methodProphecies[$methodName] = array();
|
||||
|
|
@ -168,6 +168,8 @@ class ObjectProphecy implements ProphecyInterface
|
|||
return $this->methodProphecies;
|
||||
}
|
||||
|
||||
$methodName = strtolower($methodName);
|
||||
|
||||
if (!isset($this->methodProphecies[$methodName])) {
|
||||
return array();
|
||||
}
|
||||
|
|
@ -208,12 +210,15 @@ class ObjectProphecy implements ProphecyInterface
|
|||
* Checks that registered method predictions do not fail.
|
||||
*
|
||||
* @throws \Prophecy\Exception\Prediction\AggregateException If any of registered predictions fail
|
||||
* @throws \Prophecy\Exception\Call\UnexpectedCallException
|
||||
*/
|
||||
public function checkProphecyMethodsPredictions()
|
||||
{
|
||||
$exception = new AggregateException(sprintf("%s:\n", get_class($this->reveal())));
|
||||
$exception->setObjectProphecy($this);
|
||||
|
||||
$this->callCenter->checkUnexpectedCalls();
|
||||
|
||||
foreach ($this->methodProphecies as $prophecies) {
|
||||
foreach ($prophecies as $prophecy) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
namespace Prophecy;
|
||||
|
||||
use Prophecy\Doubler\CachedDoubler;
|
||||
use Prophecy\Doubler\Doubler;
|
||||
use Prophecy\Doubler\LazyDouble;
|
||||
use Prophecy\Doubler\ClassPatch;
|
||||
|
|
@ -45,11 +46,13 @@ class Prophet
|
|||
* @param null|RevealerInterface $revealer
|
||||
* @param null|StringUtil $util
|
||||
*/
|
||||
public function __construct(Doubler $doubler = null, RevealerInterface $revealer = null,
|
||||
StringUtil $util = null)
|
||||
{
|
||||
public function __construct(
|
||||
Doubler $doubler = null,
|
||||
RevealerInterface $revealer = null,
|
||||
StringUtil $util = null
|
||||
) {
|
||||
if (null === $doubler) {
|
||||
$doubler = new Doubler;
|
||||
$doubler = new CachedDoubler();
|
||||
$doubler->registerClassPatch(new ClassPatch\SplFileInfoPatch);
|
||||
$doubler->registerClassPatch(new ClassPatch\TraversablePatch);
|
||||
$doubler->registerClassPatch(new ClassPatch\ThrowablePatch);
|
||||
|
|
|
|||
|
|
@ -181,9 +181,7 @@ class ExportUtil
|
|||
if (is_object($value)) {
|
||||
$class = get_class($value);
|
||||
|
||||
if ($value instanceof ProphecyInterface) {
|
||||
return sprintf('%s Object (*Prophecy*)', $class);
|
||||
} elseif ($hash = $processed->contains($value)) {
|
||||
if ($hash = $processed->contains($value)) {
|
||||
return sprintf('%s:%s Object', $class, $hash);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue