/** * 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(); }