/**
  * Handle intercepted calls made to the mock class instance.
  *
  * @param string                            $mockObjName
  * @param \Box\TestScribe\MethodInfo\Method $method
  * @param array                             $arguments
  *
  * @return void
  */
 public function showCallInfo($mockObjName, Method $method, array $arguments)
 {
     $methodName = $method->getName();
     $callerInfoString = $this->getCallerInfoString();
     $msg = "\n{$callerInfoString} Calling {$mockObjName}->{$methodName}( ";
     $this->output->write($msg);
     $msg = $this->methodCallInfo->getCallParamInfo($method, $arguments);
     $this->output->writeln($msg);
 }
 /**
  * Collect values of the arguments to the given method.
  *
  * @param \Box\TestScribe\MethodInfo\Method $method
  *
  * @return \Box\TestScribe\ArgumentInfo\Arguments
  */
 public function collect(Method $method)
 {
     $reflectionMethod = $method->getReflectionMethod();
     $args = $reflectionMethod->getParameters();
     $argumentsCount = count($args);
     if (!$argumentsCount) {
         return new Arguments([]);
     }
     $methodName = $reflectionMethod->getName();
     $className = $reflectionMethod->getDeclaringClass()->getName();
     $message = "\nPrepare to get arguments to the method ( {$methodName} ) of the class ( {$className} ).\n";
     $this->output->writeln($message);
     $methodParams = null;
     $testName = $this->globalComputedConfig->getTestMethodName();
     $savedSpec = $this->savedSpecs->getSpecForTest($testName);
     if ($savedSpec) {
         if ($method->isConstructor()) {
             $methodParams = $savedSpec->getConstructorParameters();
         } else {
             $methodParams = $savedSpec->getMethodParameters();
         }
     }
     $argsArray = [];
     $index = 0;
     foreach ($args as $arg) {
         $argumentName = $arg->getName();
         $argPromptSubject = "parameter ( {$argumentName} )";
         $isOptional = $arg->isOptional();
         if ($isOptional) {
             $argPromptSubject = "optional {$argPromptSubject}";
         }
         if ($methodParams) {
             // @TODO (Ray Yang 9/30/15) : error checking
             $value = $methodParams[$index];
             $this->output->writeln("Get ( {$value} ) from the saved test for {$argPromptSubject}");
             $inputValue = $this->inputValueFactory->createPrimitiveValue($value);
         } else {
             $typeInfo = $method->getParamTypeString($argumentName);
             $inputValue = $this->inputValueGetter->get($typeInfo, $argPromptSubject, '', $methodName, $argumentName);
         }
         if ($inputValue->isVoid()) {
             // @TODO (ryang 1/9/15) : double check if the parameter is optional.
             // Assume the parameters after this one will all have to be void.
             break;
         }
         $argsArray[] = $inputValue;
         $index++;
     }
     // Add an empty line for improved readability.
     $this->output->writeln('');
     $args = new Arguments($argsArray);
     return $args;
 }
 /**
  * Invoke a method on the target object regardless if the method is private, protected or public.
  *
  * @param object|null                         $targetObject null if the method is static
  * @param \Box\TestScribe\MethodInfo\Method    $method
  * @param \Box\TestScribe\ArgumentInfo\Arguments $arguments
  *
  * @return mixed
  */
 public function invokeMethodRegardlessOfProtectionLevel($targetObject, Method $method, Arguments $arguments)
 {
     $className = $method->getFullClassName();
     $argumentValues = $arguments->getValues();
     // @TODO (ryang 2/3/15) : warn against testing private methods directly.
     // @TODO (ryang 6/8/15) : only change accessibility when the method is not public
     $reflectionClass = new \ReflectionClass($className);
     $methodName = $method->getName();
     $reflectionMethod = $reflectionClass->getMethod($methodName);
     $reflectionMethod->setAccessible(true);
     $this->output->writeln("\nStart executing method ( {$methodName} ).\n");
     $executionResult = $reflectionMethod->invokeArgs($targetObject, $argumentValues);
     $this->output->writeln("\nFinish executing method ( {$methodName} ).\n");
     return $executionResult;
 }
 /**
  * Generate and return the statement for setting up one
  * mocked object method invocation expectation.
  *
  * @param Method     $methodObj
  * @param array      $arguments
  * @param InputValue $returnValue
  *
  * @return string
  */
 public function renderOneMethodExpectation(Method $methodObj, array $arguments, InputValue $returnValue)
 {
     $methodName = $methodObj->getName();
     $argString = $this->mockedMethodInvocationArgumentsRenderer->renderMockedMethodArguments($arguments);
     $expectationStatements = "\$shmock->{$methodName}({$argString});";
     // @TODO (ryang 9/12/14) : can we make this decision purely based on the $value?
     // If no return value still specify return null?
     // If the method has no return value
     // don't generate the return value mock statement.
     if (!$returnValue->isVoid()) {
         $returnValueAsString = $returnValue->getExpression();
         $returnValueCallStatement = "\$mock->return_value({$returnValueAsString});";
         $expectationStatements = "/** @var \$mock \\Shmock\\Spec */\n" . "\$mock = {$expectationStatements}\n" . "{$returnValueCallStatement}";
     }
     return $expectationStatements;
 }
 /**
  * @param \Box\TestScribe\MethodInfo\Method $method
  * @param array                            $arguments
  *
  * @return string
  * @throws \Box\TestScribe\Exception\TestScribeException
  */
 private function getDetail(Method $method, array $arguments)
 {
     // @TODO (ryang 5/28/15) : more checking if the actual parameters
     // match the function prototype.
     $expectedParameters = $method->getParameters();
     $maxExpectedCount = count($expectedParameters);
     $resultMsg = '';
     foreach ($arguments as $index => $arg) {
         // convert the scalar value to its string representation.
         $stringRepresentation = $this->valueFormatter->getReadableFormat($arg);
         if ($index < $maxExpectedCount) {
             $expectedArg = $expectedParameters[$index];
             $argumentName = $expectedArg->getName();
             $paramMsg = "  \${$argumentName} = {$stringRepresentation}";
         } else {
             $paramMsg = "This argument of value ( {$stringRepresentation} ) is unexpected.";
         }
         $resultMsg .= "\n{$paramMsg}";
     }
     return $resultMsg;
 }
 /**
  * Get the name of the method under test.
  *
  * @return string
  */
 public function getMethodName()
 {
     return $this->inMethod->getName();
 }