Наследование: extends Eloquent\Phony\Event\Event, extends Eloquent\Phony\Event\EventCollection
Пример #1
0
 /**
  * Construct a new call verifier.
  *
  * @param Call                     $call                     The call.
  * @param MatcherFactory           $matcherFactory           The matcher factory to use.
  * @param MatcherVerifier          $matcherVerifier          The matcher verifier to use.
  * @param GeneratorVerifierFactory $generatorVerifierFactory The generator verifier factory to use.
  * @param IterableVerifierFactory  $iterableVerifierFactory  The iterable verifier factory to use.
  * @param AssertionRecorder        $assertionRecorder        The assertion recorder to use.
  * @param AssertionRenderer        $assertionRenderer        The assertion renderer to use.
  */
 public function __construct(Call $call, MatcherFactory $matcherFactory, MatcherVerifier $matcherVerifier, GeneratorVerifierFactory $generatorVerifierFactory, IterableVerifierFactory $iterableVerifierFactory, AssertionRecorder $assertionRecorder, AssertionRenderer $assertionRenderer)
 {
     parent::__construct();
     $this->call = $call;
     $this->matcherFactory = $matcherFactory;
     $this->matcherVerifier = $matcherVerifier;
     $this->generatorVerifierFactory = $generatorVerifierFactory;
     $this->iterableVerifierFactory = $iterableVerifierFactory;
     $this->assertionRecorder = $assertionRecorder;
     $this->assertionRenderer = $assertionRenderer;
     $this->argumentCount = count($call->arguments());
 }
 /**
  * Create a new generator spy.
  *
  * @param Call             $call                             The call from which the generator originated.
  * @param Generator        $generator                        The generator.
  * @param CallEventFactory $callEventFactory                 The call event factory to use.
  * @param bool             $isGeneratorImplicitNextSupported True if implicit generator next() behavior is supported.
  *
  * @return Generator The newly created generator spy.
  */
 public static function createGeneratorSpy(Call $call, Generator $generator, CallEventFactory $callEventFactory, $isGeneratorImplicitNextSupported)
 {
     $call->addIterableEvent($callEventFactory->createUsed());
     $isFirst = true;
     $received = null;
     $receivedException = null;
     while (true) {
         $thrown = null;
         try {
             if ($isFirst) {
                 if (!$isGeneratorImplicitNextSupported) {
                     $generator->next();
                 }
             } else {
                 if ($receivedException) {
                     $generator->throw($receivedException);
                 } else {
                     $generator->send($received);
                 }
             }
             if (!$generator->valid()) {
                 $call->setEndEvent($callEventFactory->createReturned(null));
                 break;
             }
         } catch (Throwable $thrown) {
             // re-thrown after recording
         } catch (Exception $thrown) {
             // re-thrown after recording
         }
         if ($thrown) {
             $call->setEndEvent($callEventFactory->createThrew($thrown));
             throw $thrown;
         }
         $key = $generator->key();
         $value = $generator->current();
         $received = null;
         $receivedException = null;
         $call->addIterableEvent($callEventFactory->createProduced($key, $value));
         try {
             $received = (yield $key => $value);
             $call->addIterableEvent($callEventFactory->createReceived($received));
         } catch (Exception $receivedException) {
             $call->addIterableEvent($callEventFactory->createReceivedException($receivedException));
         }
         $isFirst = false;
         unset($value);
     }
 }
 /**
  * Create a new generator spy.
  *
  * @param Call             $call             The call from which the generator originated.
  * @param Generator        $generator        The generator.
  * @param CallEventFactory $callEventFactory The call event factory to use.
  *
  * @return Generator The newly created generator spy.
  */
 public static function createGeneratorSpy(Call $call, Generator $generator, CallEventFactory $callEventFactory)
 {
     $call->addIterableEvent($callEventFactory->createUsed());
     $isFirst = true;
     $received = null;
     $receivedException = null;
     while (true) {
         $thrown = null;
         try {
             if (!$isFirst) {
                 if ($receivedException) {
                     $generator->throw($receivedException);
                 } else {
                     $generator->send($received);
                 }
             }
             if (!$generator->valid()) {
                 $returnValue = $generator->getReturn();
                 $call->setEndEvent($callEventFactory->createReturned($returnValue));
                 return $returnValue;
             }
         } catch (Throwable $thrown) {
             // re-thrown after recording
             // @codeCoverageIgnoreStart
         } catch (Exception $thrown) {
             // re-thrown after recording
         }
         // @codeCoverageIgnoreEnd
         if ($thrown) {
             $call->setEndEvent($callEventFactory->createThrew($thrown));
             throw $thrown;
         }
         $key = $generator->key();
         $value = $generator->current();
         $received = null;
         $receivedException = null;
         $call->addIterableEvent($callEventFactory->createProduced($key, $value));
         try {
             $received = (yield $key => $value);
             $call->addIterableEvent($callEventFactory->createReceived($received));
         } catch (Exception $receivedException) {
             $call->addIterableEvent($callEventFactory->createReceivedException($receivedException));
         }
         $isFirst = false;
         unset($value);
     }
 }
Пример #4
0
 /**
  * Render a failed generator threw() verification.
  *
  * @param Spy|Call                            $subject     The subject.
  * @param Cardinality                         $cardinality The cardinality.
  * @param Matcher|Exception|Error|string|null $type        The type of exception.
  *
  * @return string The rendered failure message.
  */
 public function renderGeneratorThrew($subject, Cardinality $cardinality, $type)
 {
     $isCall = $subject instanceof Call;
     if ($isCall) {
         $calls = array($subject);
         $renderedCallee = $this->exporter->exportCallable($subject->callback());
     } else {
         $calls = $subject->allCalls();
         $renderedCallee = $this->exporter->exportCallable($subject);
     }
     $renderedSubject = $this->bold . $renderedCallee . $this->reset;
     $minimum = $cardinality->minimum();
     $maximum = $cardinality->maximum();
     $isNever = null !== $maximum && $maximum < 1;
     if ($isCall) {
         $totalCount = 1;
         $iterableCount = 1;
         $renderedIterableCount = '';
     } else {
         $iterableCount = 0;
         foreach ($calls as $call) {
             if ($call->isGenerator()) {
                 ++$iterableCount;
             }
         }
         $totalCount = $iterableCount;
         if ($cardinality->matches($iterableCount, $iterableCount)) {
             $iterableResultStart = $this->passStart;
         } else {
             $iterableResultStart = $this->failStart;
         }
         $matchOrMatches = 1 === $iterableCount ? 'match' : 'matches';
         $renderedIterableCount = ' ' . $iterableResultStart . $this->faint . '(' . $iterableCount . ' ' . $matchOrMatches . ')' . $this->reset;
     }
     if ($iterableCount xor $isNever) {
         $iterableResult = $this->pass;
     } else {
         $iterableResult = $this->fail;
     }
     if ($type instanceof Matcher) {
         $renderedType = $type->describe($this->exporter);
     } elseif (is_string($type)) {
         $renderedType = $type;
     } else {
         $renderedType = '<any>';
     }
     $renderedCriteria = 'behave like:' . PHP_EOL . '    ' . $iterableResult . ' Returned Generator, then:' . $renderedIterableCount . PHP_EOL . '        ' . $this->fail . ' Threw ' . $renderedType;
     if ($isCall) {
         if ($isNever) {
             $expected = 'Expected ' . $renderedSubject . ' call #' . $subject->index() . ' not to ' . $renderedCriteria;
         } else {
             $expected = 'Expected ' . $renderedSubject . ' call #' . $subject->index() . ' to ' . $renderedCriteria;
         }
     } else {
         if ($isNever) {
             $expected = 'Expected ' . $renderedSubject . ' generator calls not to ' . $renderedCriteria;
         } elseif ($cardinality->isAlways()) {
             $expected = 'Expected all ' . $renderedSubject . ' generator calls to ' . $renderedCriteria;
         } else {
             $expected = 'Expected ' . $renderedSubject . ' generator calls to ' . $renderedCriteria;
         }
     }
     $renderedCalls = array();
     $matchCount = 0;
     foreach ($calls as $call) {
         $callIsRelevant = $call->isGenerator();
         if ($callIsRelevant) {
             $callStart = '';
             $callEnd = '';
         } else {
             $callStart = $this->faint;
             $callEnd = $this->reset;
         }
         $isMatchingCall = false;
         $renderedArguments = array();
         foreach ($call->arguments()->all() as $argument) {
             $renderedArguments[] = $this->exporter->export($argument, 0);
         }
         $responseEvent = $call->responseEvent();
         if ($responseEvent instanceof ReturnedEvent) {
             $returnValue = $responseEvent->value();
             if (is_array($returnValue) || $returnValue instanceof Traversable) {
                 $iterableEvents = $call->iterableEvents();
                 $renderedIterableEvents = array();
                 foreach ($iterableEvents as $event) {
                     if ($event instanceof UsedEvent) {
                         $renderedIterableEvents[] = '        - Started iterating';
                     } elseif ($event instanceof ProducedEvent) {
                         $iterableKey = $event->key();
                         $iterableValue = $event->value();
                         $renderedIterableEvents[] = '        - Produced ' . $this->exporter->export($iterableKey) . ' => ' . $this->exporter->export($iterableValue);
                     } elseif ($event instanceof ReceivedEvent) {
                         $iterableValue = $event->value();
                         $renderedIterableEvents[] = '        - Received ' . $this->exporter->export($iterableValue);
                     } elseif ($event instanceof ReceivedExceptionEvent) {
                         $iterableException = $event->exception();
                         $renderedIterableEvents[] = '        - Received exception ' . $this->exporter->export($iterableException);
                     }
                 }
                 $endEvent = $call->endEvent();
                 if (empty($iterableEvents)) {
                     if ($callIsRelevant) {
                         if ($isNever) {
                             $eventResult = $this->pass;
                         } else {
                             $eventResult = $this->fail;
                         }
                     } else {
                         $eventResult = '-';
                     }
                     $renderedIterableEvents[] = '        ' . $eventResult . ' Never started iterating';
                 } elseif ($endEvent instanceof ConsumedEvent) {
                     $renderedIterableEvents[] = '        - Finished iterating';
                 } elseif ($endEvent instanceof ReturnedEvent) {
                     $iterableValue = $endEvent->value();
                     if ($isNever) {
                         $eventResult = $this->pass;
                     } else {
                         $eventResult = $this->fail;
                     }
                     $renderedIterableEvents[] = '        ' . $eventResult . ' Returned ' . $this->exporter->export($iterableValue);
                 } elseif ($endEvent instanceof ThrewEvent) {
                     $iterableException = $endEvent->exception();
                     $renderedIterableException = $this->exporter->export($iterableException);
                     if ($type instanceof Matcher) {
                         $eventIsMatch = $type->matches($iterableException);
                     } elseif (is_string($type)) {
                         $eventIsMatch = is_a($iterableException, $type);
                     } else {
                         $eventIsMatch = true;
                     }
                     if ($eventIsMatch) {
                         ++$matchCount;
                         $isMatchingCall = true;
                     } elseif ($type instanceof EqualToMatcher) {
                         $renderedIterableException = $this->differenceEngine->difference($renderedType, $renderedIterableException);
                     }
                     if ($eventIsMatch xor $isNever) {
                         $eventResult = $this->pass;
                     } else {
                         $eventResult = $this->fail;
                     }
                     $renderedIterableEvents[] = '        ' . $eventResult . ' Threw ' . $renderedIterableException;
                 } else {
                     if ($callIsRelevant) {
                         if ($isNever) {
                             $eventResult = $this->pass;
                         } else {
                             $eventResult = $this->fail;
                         }
                     } else {
                         $eventResult = '-';
                     }
                     $renderedIterableEvents[] = '        ' . $eventResult . ' Never finished iterating';
                 }
                 $renderedResponse = 'Returned ' . $this->exporter->export($returnValue, 0) . ', then:' . $callEnd . PHP_EOL . $callStart . implode($callEnd . PHP_EOL . $callStart, $renderedIterableEvents);
             } else {
                 $renderedResponse = 'Returned ' . $this->exporter->export($returnValue);
             }
         } elseif ($responseEvent instanceof ThrewEvent) {
             $exception = $responseEvent->exception();
             $renderedResponse = 'Threw ' . $this->exporter->export($exception);
         } else {
             $renderedResponse = 'Never responded';
         }
         if ($callIsRelevant) {
             if ($isMatchingCall xor $isNever) {
                 $renderedResult = $this->pass;
             } else {
                 $renderedResult = $this->fail;
             }
         } else {
             $renderedResult = '-';
         }
         $renderedCalls[] = $callStart . $renderedResult . ' Call #' . $call->index() . ' - ' . $renderedCallee . '(' . implode(', ', $renderedArguments) . '):' . $callEnd . PHP_EOL . $callStart . '    ' . $renderedResult . ' ' . $renderedResponse . $callEnd;
     }
     $actual = PHP_EOL . implode(PHP_EOL, $renderedCalls);
     if ($isCall) {
         $cardinality = '';
     } else {
         $cardinality = $this->renderCardinality($minimum, $maximum, $matchCount, $totalCount, $totalCount, false);
     }
     return $this->reset . $expected . $cardinality . $actual;
 }