/** * Return statements for invoking the test. * * @param bool $shouldVerifyResult * @param string $argumentsString * @param string $targetObjectName * * @return string */ public function genExecutionStatements($shouldVerifyResult, $argumentsString, $targetObjectName) { if ($shouldVerifyResult) { // The space character has to be included here // instead of the place where string concatenation happens // because when the string is empty, we don't want to // include an extra space character. $assignmentStr = '$executionResult = '; } else { // If the return value type of the method under test is void // don't assign the return value to a local variable. // Otherwise intellij will warn you about using such a value. $assignmentStr = ''; } $isPublic = $this->globalComputedConfig->isMethodPublic(); $isStatic = $this->globalComputedConfig->isMethodStatic(); $fullClassName = $this->globalComputedConfig->getFullClassName(); $methodName = $this->globalComputedConfig->getMethodName(); if ($isPublic) { if ($isStatic) { $invocationStatement = "{$assignmentStr}{$fullClassName}::{$methodName}({$argumentsString});"; } else { $invocationStatement = "{$assignmentStr}\${$targetObjectName}->{$methodName}({$argumentsString});"; } } else { $invocationStatement = $this->nonPublicMethodExecutionRenderer->genNonPublicExecutionStatements($assignmentStr, $isStatic, $fullClassName, $methodName, $argumentsString, $targetObjectName); } return $invocationStatement; }
/** * @param string $dataString * * @return void */ private function writeDataStringToFile($dataString) { $historyFilePath = $this->globalComputedConfig->getHistoryFile(); if (!$this->globalFunction->file_exists($historyFilePath)) { $this->fileUtil->createDirectoriesWhenNeededForFile($historyFilePath); } $this->globalFunction->file_put_contents($historyFilePath, $dataString); }
/** * @param \Box\TestScribe\Execution\ExecutionResult $executionResult * * @return void */ public function genSpec(ExecutionResult $executionResult) { // This method assumes that the saved specs have been loaded. $specsPerClass = $this->savedSpecs->getSpecPerClass(); $oneSpec = $this->specDetailRenderer->genSpecDetail($executionResult); $methodName = $this->globalComputedConfig->getMethodName(); $newSpecsPerClass = $this->specsPerClassService->addOneSpec($specsPerClass, $methodName, $oneSpec); $this->savedSpecs->saveNewSpec($newSpecsPerClass); }
/** * @return \Box\TestScribe\Execution\ExecutionResult * @throws \Box\TestScribe\Exception\AbortException * @throws \Box\TestScribe\Exception\TestScribeException */ public function runMethod() { $isStatic = $this->globalComputedConfig->isMethodStatic(); if ($isStatic) { $executionResult = $this->staticMethodExecutor->runStaticMethod(); } else { $executionResult = $this->instanceMethodExecutor->runInstanceMethod(); } return $executionResult; }
/** * Generate an OneSpec instance from the execution result. * * @param \Box\TestScribe\Execution\ExecutionResult $executionResult * * @return \Box\TestScribe\Spec\OneSpec */ public function genSpecDetail(ExecutionResult $executionResult) { $testName = $this->globalComputedConfig->getTestMethodName(); $result = $executionResult->getResultValue(); $methodArguments = $executionResult->getMethodArguments(); $methodParameters = $methodArguments->getValues(); $constructorArguments = $executionResult->getConstructorArguments(); $constructorParameters = $constructorArguments->getValues(); $mockSpecs = $this->allMockSpecs->getAllMockSpecs(); $oneSpec = new OneSpec($testName, $result, $constructorParameters, $methodParameters, $mockSpecs); return $oneSpec; }
/** * Return statements for invoking the test and verifying the result. * * @param \Box\TestScribe\Execution\ExecutionResult $executionResult * * @param string $targetObjectName * * @return string */ public function genExecutionAndVerification(ExecutionResult $executionResult, $targetObjectName) { $exception = $executionResult->getException(); $isReturnTypeVoid = $this->globalComputedConfig->isReturnTypeVoid(); $shouldVerifyResult = $exception === null && !$isReturnTypeVoid; $methodArguments = $executionResult->getMethodArguments(); $argumentsString = $this->argumentsRenderer->renderArgumentsAsStringInCode($methodArguments); $executionStatements = $this->executionRenderer->genExecutionStatements($shouldVerifyResult, $argumentsString, $targetObjectName); $resultValidationStatements = $this->resultValidationRenderer->genResultValidation($shouldVerifyResult, $executionResult); $result = ArrayUtil::joinNonEmptyStringsWithNewLine([$executionStatements, $resultValidationStatements], 2); return $result; }
/** * If the call of the given frame index is a call from the class being tested. * * @param int $distanceFromThisCall * e.g. * bar calls foo, foo calls this method * To check about foo, specify 1. * To check about bar, specify 2. * * @return bool * @throws \Box\TestScribe\Exception\TestScribeException */ public function isCallFromTheClassBeingTested($distanceFromThisCall) { // The file path should be an absolute path. $inputSourceFilePath = $this->globalComputedConfig->getInSourceFile(); // Add one to the distance to take into consideration of the // additional frame between this call and // $this->callInformationCollector->getCallerInfoAt $callInfo = $this->callInformationCollector->getCallerInfoAt($distanceFromThisCall + 1); $filePathOfTheCaller = $callInfo->getFileName(); $isImmediateCall = $inputSourceFilePath === $filePathOfTheCaller; return $isImmediateCall; }
/** * 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; }
/** * Generate statements for setting up the mocks of the classes * injected by the dependency management system. * Static methods are expected to be invoked on these mocks. * * @return string * @throws \Box\TestScribe\Exception\TestScribeException */ public function genMockedClassesStatements() { $mocks = $this->injectedMockClassMgr->getInjectedMockedClass(); if (empty($mocks)) { return ''; } $injectMockedClassMethodName = $this->globalComputedConfig->getInjectMockedClassMethodName(); if (!$injectMockedClassMethodName) { throw new TestScribeException('Method name to generate statements for setting up mocked classes is not set.'); } $statements = $this->multipleInjectedMocksRenderer->genInjectionStatements($mocks, $injectMockedClassMethodName); return $statements; }
/** * Execute the method under test and generate a test for it. * * @return void */ public function start() { try { $executionResult = $this->runner->run(); } catch (AbortException $ex) { $this->inputHistory->saveHistoryToFile(); return; } $this->inputHistory->saveHistoryToFile(); $this->rendererService->render($executionResult); if ($this->globalComputedConfig->isGenerateSpec()) { $this->specRenderer->genSpec($executionResult); } }
/** * @param callable $func * @param array $params * * @return \Box\TestScribe\Execution\ExecutionResultWithExceptionValue * @throws \Box\TestScribe\Exception\AbortException * @throws \Box\TestScribe\Exception\TestScribeException * @throws \Exception */ public function execute(callable $func, array $params) { $result = null; $exceptionFromExecution = null; try { $result = call_user_func_array($func, $params); } catch (AbortException $abortException) { throw $abortException; } catch (TestScribeException $testScribeException) { if ($this->globalComputedConfig->isTheTestRunAgainstTheToolItself()) { $exceptionFromExecution = $testScribeException; } else { // Chain the original exception to provide details on the original exception. ExceptionUtil::rethrowSameException($testScribeException); } } catch (\Exception $exception) { $exceptionFromExecution = $exception; } $returnValue = new ExecutionResultWithExceptionValue($result, $exceptionFromExecution); return $returnValue; }
/** * @param PhpClassName $outPhpClassName * * @return string */ public function renderClassHeader(PhpClassName $outPhpClassName) { $classNamespace = $outPhpClassName->getNameSpace(); if ($classNamespace != '') { $namespaceStatement = "namespace {$classNamespace};"; } else { $namespaceStatement = ''; } $testClassName = $outPhpClassName->getClassName(); $testBaseClassName = $this->globalComputedConfig->getTestBaseClassName(); $headerStatements = <<<TAG <?php {$namespaceStatement} /** * Generated by TestScribe. */ class {$testClassName} extends {$testBaseClassName} TAG; return $headerStatements; }
/** * Delete the existing destination file if it exists * and the command line option is specified to overwrite it. * * @param string $file */ private function deleteExistingDestinationFileWhenNeeded($file) { if (file_exists($file) && $this->globalComputedConfig->isOverwriteExistingDestinationFile()) { unlink($file); } }