/**
  * Return the specsPerMethod for the given method.
  *
  * If the method key doesn't exist, an empty spec set
  * will be returned.
  *
  * @param $methodName
  *
  * @return \Box\TestScribe\Spec\SpecsPerMethod
  */
 public function getSpecsPerMethodByName($methodName)
 {
     $default = new SpecsPerMethod($methodName, []);
     /** @var SpecsPerMethod $specsPerMethod */
     $specsPerMethod = ArrayUtil::lookupValueByKey($methodName, $this->specs, $default);
     return $specsPerMethod;
 }
 /**
  * @param \Box\TestScribe\Mock\MockClass $mockClass
  * @param string                              $injectMethodName
  *
  * @return string
  */
 public function genInjectedMockStatement(MockClass $mockClass, $injectMethodName)
 {
     $createMockObjectStatement = $this->mockRenderer->renderAMock($mockClass);
     $injectStatement = $this->genInjectionStatement($mockClass, $injectMethodName);
     // @TODO (ryang 8/6/14) : better handling of indentations.
     $combinedStatements = ArrayUtil::joinNonEmptyStringsWithNewLine([$createMockObjectStatement, $injectStatement], 1);
     return $combinedStatements;
 }
 /**
  * Generate the test method as a string.
  *
  * @param \Box\TestScribe\Execution\ExecutionResult   $executionResult
  *
  * @return string
  */
 public function renderMethodBody(ExecutionResult $executionResult)
 {
     $objectInjectionStatements = $this->injectedMocksRenderer->renderObjectInjectionStatements();
     $exceptionExpectationStatements = $this->exceptionRenderer->genExceptionExpectation($executionResult);
     $methodInvocationStatements = $this->invocationRenderer->renderMethodInvocation($executionResult);
     // @TODO (ryang 6/3/15) : move exception expectation statement after all the mocks statements.
     $methodBody = ArrayUtil::joinNonEmptyStringsWithNewLine([$objectInjectionStatements, $exceptionExpectationStatements, $methodInvocationStatements], 2);
     return $methodBody;
 }
 /**
  * Generate statements for setting up the mocks of the objects
  * injected by the dependency management system.
  *
  * @return string
  */
 public function renderObjectInjectionStatements()
 {
     $objectInjectionStatements = $this->injectedMockObjectsRenderer->genMockedObjectStatements();
     $mockClassInjectionStatements = $this->injectedMockClassesRenderer->genMockedClassesStatements();
     $combinedStatements = ArrayUtil::joinNonEmptyStringsWithNewLine([$objectInjectionStatements, $mockClassInjectionStatements], 2);
     $comment = "// Setup mocks injected by the dependency management system.\n\n";
     $result = Util::appendStringIfNotEmpty($comment, $combinedStatements);
     return $result;
 }
 /**
  * Return the last used raw input string for the item.
  * 
  * @param string $sectionName 
  *  either method name of the class under test
  *  or dependent class name
  * 
  * @param string $itemName
  *   either parameter name
  *   or dependent class's method name
  *
  * @return string
  */
 public function getInputStringFromHistory($sectionName, $itemName)
 {
     $inputString = '';
     $sectionArray = ArrayUtil::lookupValueByKey($sectionName, $this->data, null);
     if ($sectionArray !== null) {
         $inputString = ArrayUtil::lookupValueByKey($itemName, $sectionArray, '');
     }
     return $inputString;
 }
 /**
  * Return the statements that sets the expectations and
  * return values of the method invocation of the mocked
  * object.
  *
  * @param MockClass $mock
  *
  * @return string
  */
 public function renderMethodExpectations(MockClass $mock)
 {
     $mockedExpectationsArray = [];
     foreach ($mock->getMethodInvocations() as $invocation) {
         list($methodObj, $arguments, $value) = $invocation;
         $mockedOneExpectation = $this->mockMethodExpectationRenderer->renderOneMethodExpectation($methodObj, $arguments, $value);
         $mockedExpectationsArray[] = $mockedOneExpectation;
     }
     $mockedExpectations = ArrayUtil::joinNonEmptyStringsWithNewLine($mockedExpectationsArray, 2);
     return $mockedExpectations;
 }
 /**
  * Generate all injection statements for either mock classes or mock objects.
  *
  * @param array  $mocks
  *   class name string => MockClass
  * @param string $injectMethodName
  *
  * @return string
  */
 public function genInjectionStatements($mocks, $injectMethodName)
 {
     $statementArray = [];
     /* @var $mock \Box\TestScribe\Mock\MockClass */
     foreach ($mocks as $mock) {
         $statement = $this->oneInjectedMockRenderer->genInjectedMockStatement($mock, $injectMethodName);
         $statementArray[] = $statement;
     }
     $combinedStatements = ArrayUtil::joinNonEmptyStringsWithNewLine($statementArray, 2);
     return $combinedStatements;
 }
 /**
  * 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;
 }
 /**
  * Generate the argument list as a string and
  * its referenced mock statements.
  *
  * @param \Box\TestScribe\ArgumentInfo\Arguments $argsObj
  *
  * @return \Box\TestScribe\Renderers\ArgumentsRenderResult
  */
 public function renderArguments(Arguments $argsObj)
 {
     $expressions = $argsObj->getExpressions();
     $argumentsString = implode(', ', $expressions);
     $mocks = $argsObj->getMocks();
     $mockObjectStatementArray = [];
     foreach ($mocks as $mock) {
         $mockObjectStatement = $this->mockRenderer->renderAMock($mock);
         $mockObjectStatementArray[] = $mockObjectStatement;
     }
     $mockObjectStatementsString = ArrayUtil::joinNonEmptyStringsWithNewLine($mockObjectStatementArray, 2);
     $result = new ArgumentsRenderResult($argumentsString, $mockObjectStatementsString);
     return $result;
 }
 /**
  * @param array $data
  *
  * @return \Box\TestScribe\Spec\OneSpec
  */
 public function loadOneSpec($data)
 {
     $testName = $data[self::TEST_NAME];
     $methodParameters = $data[self::METHOD_PARAM];
     $result = $data[self::RESULT_KEY];
     $mocksData = ArrayUtil::lookupValueByKey(self::MOCK, $data, []);
     $mockSpecs = [];
     foreach ($mocksData as $oneMockData) {
         $oneMockSpec = $this->mockSpecPersistence->loadMockSpec($oneMockData);
         $mockSpecs[] = $oneMockSpec;
     }
     $constructorParameters = ArrayUtil::lookupValueByKey(self::CONSTRUCTOR_PARAM, $data, []);
     $oneSpec = new OneSpec($testName, $result, $constructorParameters, $methodParameters, $mockSpecs);
     return $oneSpec;
 }
 /**
  * Generate assertions of an object.
  *
  * @param string  $variableName name without '$' prefix
  * @param \object $value
  *
  * @return string
  */
 public function generateForAnObject($variableName, $value)
 {
     $objectTypeString = get_class($value);
     $isMockObject = $this->mockClassUtil->isMockClass($objectTypeString);
     $typeCheckStatement = $this->renderObjectTypeAssertion($isMockObject, $variableName, $value);
     if ($isMockObject) {
         // Calling methods on mocked object at the rendering phase can
         // confuse users where the call comes from.
         // Don't call json_encode() method here.
         // @TODO (ryang 12/19/14) : re-evaluate when we start supporting non shmock based mocking
         // frameworks
         $valueCheckStatement = '';
     } else {
         $valueCheckStatement = $this->renderObjectValueAssertion($variableName, $value);
     }
     $statements = ArrayUtil::joinNonEmptyStringsWithNewLine([$typeCheckStatement, $valueCheckStatement], 2);
     return $statements;
 }
 /**
  * @param \Symfony\Component\Console\Input\InputInterface $input
  * @param string                                          $inSourceFile
  *
  * @return \Box\TestScribe\Config\Options
  */
 public function getOptions(InputInterface $input, $inSourceFile)
 {
     $configFilePath = $this->configHelper->getConfigFilePath($input);
     $generateSpec = false;
     $testBaseClassName = self::DEFAULT_TEST_BASE_CLASS_NAME;
     if ($configFilePath) {
         $data = $this->yamlUtil->loadYamlFile($configFilePath);
         $generateSpec = ArrayUtil::lookupBoolValue(self::GENERATE_SPEC_KEY, $data, false);
         $testBaseClassName = ArrayUtil::lookupStringValue(self::TEST_BASE_CLASS_NAME_KEY, $data, self::DEFAULT_TEST_BASE_CLASS_NAME);
     }
     $overwriteExistingDestinationFile = $input->getOption(CmdOption::OVERWRITE_EXISTING_DESTINATION_FILE_OPTION);
     $testFileRoot = $this->configHelper->getTestRootPath($input);
     $sourceFileRoot = $this->configHelper->getSourceFileRoot($input, $testFileRoot, $inSourceFile);
     $sourceFilePathRelativeToSourceRoot = $this->configHelper->getSourceFilePathRelativeToSourceRoot($sourceFileRoot, $inSourceFile);
     $outSourceFileDir = PathUtil::getPathUnderRoot($testFileRoot, $sourceFilePathRelativeToSourceRoot);
     $inputOptions = new Options($overwriteExistingDestinationFile, $testFileRoot, $sourceFileRoot, $outSourceFileDir, $sourceFilePathRelativeToSourceRoot, $generateSpec, $testBaseClassName);
     return $inputOptions;
 }
 /**
  * @param int $distanceFromThisCall
  *   e.g.
  *   bar calls foo, foo calls this method
  *   To get information about foo, specify 1.
  *   To get information about bar, specify 2. 
  *
  * @return \Box\TestScribe\Utils\CallInfo
  * @throws \Box\TestScribe\Exception\TestScribeException
  */
 public function getCallerInfoAt($distanceFromThisCall)
 {
     // This call frame and
     // $this->stackTraceFunctionWrapper->debugBacktrace()
     // add two frames on top.
     // Note that the frameIndex is 0 based.
     // And the file and line information refer to the caller
     // of the method in the frame.
     // Thus they offset each other.
     $frameIndex = $distanceFromThisCall;
     $stackFrames = $this->stackTraceFunctionWrapper->debugBacktrace();
     $totalFrames = count($stackFrames);
     if ($totalFrames <= $frameIndex) {
         $exceptionMsg = "Requested frame ( {$frameIndex} ) is out of range." . " Total frames ( {$totalFrames} )";
         throw new TestScribeException($exceptionMsg);
     }
     $targetFrame = $stackFrames[$frameIndex];
     $fileName = ArrayUtil::lookupValueByKey('file', $targetFrame, 'unknown');
     $lineNumberString = ArrayUtil::lookupValueByKey('line', $targetFrame, 'unknown');
     $callerInfo = new CallInfo($fileName, $lineNumberString);
     return $callerInfo;
 }
Example #14
0
 /**
  * @param \Box\TestScribe\Mock\MockClass $mock
  *
  * @return string
  *
  * Define this method in a separate class causes circular dependencies.
  * i.e. these two methods depend on each other.
  */
 public function renderMockedReturnValue(MockClass $mock)
 {
     $statementsArray = [];
     $mocks = $mock->getMockedReturnValues();
     if ($mocks) {
         $statementsArray[] = "// Set up mocks of return values.";
         foreach ($mocks as $mockedReturnValueObj) {
             $oneMockStatement = $this->renderAMock($mockedReturnValueObj);
             $statementsArray[] = $oneMockStatement;
         }
     }
     $statementsString = ArrayUtil::joinNonEmptyStringsWithNewLine($statementsArray, 2);
     return $statementsString;
 }
 /**
  * @param $testName
  *
  * @return OneSpec|null
  */
 public function getSpecForTest($testName)
 {
     /** @var OneSpec $spec */
     $spec = ArrayUtil::lookupValueByKey($testName, $this->specs, null);
     return $spec;
 }
 /**
  * Return statements for invoking the test and verifying the result.
  *
  * @param \Box\TestScribe\Execution\ExecutionResult $executionResult
  *
  * @return string
  */
 public function renderMethodInvocation(ExecutionResult $executionResult)
 {
     $mockClassUnderTest = $executionResult->getMockClassUnderTest();
     $config = $this->globalComputedConfig;
     $inMethod = $config->getInMethod();
     $reflectionMethod = $inMethod->getReflectionMethod();
     $isStatic = $reflectionMethod->isStatic();
     $fullyQualifiedClassName = $config->getFullClassName();
     $constructorArguments = $executionResult->getConstructorArguments();
     $constructorArgumentsRenderedResult = $this->argumentsRenderer->renderArguments($constructorArguments);
     $constructorArgumentsString = $constructorArgumentsRenderedResult->getArgumentString();
     $mockObjectForConstructorStatements = $constructorArgumentsRenderedResult->getMockStatements();
     if ($mockObjectForConstructorStatements) {
         $mockObjectForConstructorStatements = "// Setup mocks for parameters to the constructor.\n\n" . $mockObjectForConstructorStatements;
     }
     $methodArguments = $executionResult->getMethodArguments();
     $argumentsToTheMethodRenderedResult = $this->argumentsRenderer->renderArguments($methodArguments);
     $mockMethodArgumentsStatements = $argumentsToTheMethodRenderedResult->getMockStatements();
     if ($mockMethodArgumentsStatements) {
         $mockMethodArgumentsStatements = "// Setup mocks for parameters to the method under test.\n\n" . $mockMethodArgumentsStatements;
     }
     $mockAndComment = ArrayUtil::joinNonEmptyStringsWithNewLine(["{$mockMethodArgumentsStatements}", "// Execute the method under test."], 2);
     $isPartialMocking = $this->partialMockUtil->isClassUnderTestPartiallyMocked($mockClassUnderTest);
     $createObjectWithMocksStatement = '';
     $targetObjectName = '';
     if (!$isStatic) {
         if ($isPartialMocking) {
             // @TODO (ryang 3/4/15) : move the generated mock statements for the constructor into this scope.
             $createObjectWithMocksStatement = $this->mockRenderer->renderPartialMock($mockClassUnderTest, $constructorArgumentsString, $mockObjectForConstructorStatements);
             $targetObjectName = $mockClassUnderTest->getMockObjectName();
         } else {
             $targetObjectName = 'objectUnderTest';
             $createObjectStatement = "\${$targetObjectName} = new {$fullyQualifiedClassName}({$constructorArgumentsString});";
             $createObjectWithMocksStatement = ArrayUtil::joinNonEmptyStringsWithNewLine([$mockObjectForConstructorStatements, $createObjectStatement], 2);
         }
     }
     $invocationStatement = $this->executionAndVerificationRenderer->genExecutionAndVerification($executionResult, $targetObjectName);
     $result = ArrayUtil::joinNonEmptyStringsWithNewLine([$mockAndComment, $createObjectWithMocksStatement, $invocationStatement], 2);
     return $result;
 }
 /**
  * @covers \Box\TestScribe\Utils\ArrayUtil::lookupBoolValue
  * @covers \Box\TestScribe\Utils\ArrayUtil
  */
 public function test_wrong_default_value_type_raise_exception()
 {
     $this->setExpectedException('Box\\TestScribe\\Exception\\TestScribeException');
     // Execute the method under test.
     \Box\TestScribe\Utils\ArrayUtil::lookupBoolValue('k', ['another' => true], 'a');
 }