| Current Path : /var/www/html/vendor/codeception/codeception/src/Codeception/Test/ |
| Current File : /var/www/html/vendor/codeception/codeception/src/Codeception/Test/Cest.php |
<?php
namespace Codeception\Test;
use Codeception\Example;
use Codeception\Lib\Console\Message;
use Codeception\Lib\Parser;
use Codeception\Step\Comment;
use Codeception\Util\Annotation;
use Codeception\Util\ReflectionHelper;
/**
* Executes tests delivered in Cest format.
*
* Handles loading of Cest cases, executing specific methods, following the order from `@before` and `@after` annotations.
*/
class Cest extends Test implements
Interfaces\ScenarioDriven,
Interfaces\Reported,
Interfaces\Dependent,
Interfaces\StrictCoverage
{
use Feature\ScenarioLoader;
/**
* @var Parser
*/
protected $parser;
protected $testClassInstance;
protected $testMethod;
public function __construct($testClass, $methodName, $fileName)
{
$metadata = new Metadata();
$metadata->setName($methodName);
$metadata->setFilename($fileName);
$this->setMetadata($metadata);
$this->testClassInstance = $testClass;
$this->testMethod = $methodName;
$this->createScenario();
$this->parser = new Parser($this->getScenario(), $this->getMetadata());
}
public function preload()
{
$this->scenario->setFeature($this->getSpecFromMethod());
$code = $this->getSourceCode();
$this->parser->parseFeature($code);
$this->getMetadata()->setParamsFromAnnotations(Annotation::forMethod($this->testClassInstance, $this->testMethod)->raw());
$this->getMetadata()->getService('di')->injectDependencies($this->testClassInstance);
// add example params to feature
if ($this->getMetadata()->getCurrent('example')) {
$step = new Comment('', $this->getMetadata()->getCurrent('example'));
$this->getScenario()->setFeature($this->getScenario()->getFeature() . ' | '. $step->getArgumentsAsString(100));
}
}
public function getSourceCode()
{
$method = new \ReflectionMethod($this->testClassInstance, $this->testMethod);
$start_line = $method->getStartLine() - 1; // it's actually - 1, otherwise you wont get the function() block
$end_line = $method->getEndLine();
$source = file($method->getFileName());
return implode("", array_slice($source, $start_line, $end_line - $start_line));
}
public function getSpecFromMethod()
{
$text = $this->testMethod;
$text = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\\1 \\2', $text);
$text = preg_replace('/([a-z\d])([A-Z])/', '\\1 \\2', $text);
$text = strtolower($text);
return $text;
}
public function test()
{
$actorClass = $this->getMetadata()->getCurrent('actor');
$I = new $actorClass($this->getScenario());
try {
$this->executeHook($I, 'before');
$this->executeBeforeMethods($this->testMethod, $I);
$this->executeTestMethod($I);
$this->executeAfterMethods($this->testMethod, $I);
$this->executeHook($I, 'passed');
} catch (\Exception $e) {
$this->executeHook($I, 'failed');
// fails and errors are now handled by Codeception\PHPUnit\Listener
throw $e;
} finally {
$this->executeHook($I, 'after');
}
}
protected function executeHook($I, $hook)
{
if (is_callable([$this->testClassInstance, "_$hook"])) {
$this->invoke("_$hook", [$I, $this->scenario]);
}
}
protected function executeBeforeMethods($testMethod, $I)
{
$annotations = \PHPUnit\Util\Test::parseTestMethodAnnotations(get_class($this->testClassInstance), $testMethod);
if (!empty($annotations['method']['before'])) {
foreach ($annotations['method']['before'] as $m) {
$this->executeContextMethod(trim($m), $I);
}
}
}
protected function executeAfterMethods($testMethod, $I)
{
$annotations = \PHPUnit\Util\Test::parseTestMethodAnnotations(get_class($this->testClassInstance), $testMethod);
if (!empty($annotations['method']['after'])) {
foreach ($annotations['method']['after'] as $m) {
$this->executeContextMethod(trim($m), $I);
}
}
}
protected function executeContextMethod($context, $I)
{
if (method_exists($this->testClassInstance, $context)) {
$this->executeBeforeMethods($context, $I);
$this->invoke($context, [$I, $this->scenario]);
$this->executeAfterMethods($context, $I);
return;
}
throw new \LogicException(
"Method $context defined in annotation but does not exist in " . get_class($this->testClassInstance)
);
}
protected function invoke($methodName, array $context)
{
foreach ($context as $class) {
$this->getMetadata()->getService('di')->set($class);
}
$this->getMetadata()->getService('di')->injectDependencies($this->testClassInstance, $methodName, $context);
}
protected function executeTestMethod($I)
{
if (!method_exists($this->testClassInstance, $this->testMethod)) {
throw new \Exception("Method {$this->testMethod} can't be found in tested class");
}
if ($this->getMetadata()->getCurrent('example')) {
$this->invoke($this->testMethod, [$I, $this->scenario, new Example($this->getMetadata()->getCurrent('example'))]);
return;
}
$this->invoke($this->testMethod, [$I, $this->scenario]);
}
public function toString()
{
return sprintf('%s: %s', ReflectionHelper::getClassShortName($this->getTestClass()), Message::ucfirst($this->getFeature()));
}
public function getSignature()
{
return get_class($this->getTestClass()) . ":" . $this->getTestMethod();
}
public function getTestClass()
{
return $this->testClassInstance;
}
public function getTestMethod()
{
return $this->testMethod;
}
/**
* @return array
*/
public function getReportFields()
{
return [
'file' => $this->getFileName(),
'name' => $this->getTestMethod(),
'class' => get_class($this->getTestClass()),
'feature' => $this->getFeature()
];
}
protected function getParser()
{
return $this->parser;
}
public function fetchDependencies()
{
$names = [];
foreach ($this->getMetadata()->getDependencies() as $required) {
if ((strpos($required, ':') === false) and method_exists($this->getTestClass(), $required)) {
$required = get_class($this->getTestClass()) . ":$required";
}
$names[] = $required;
}
return $names;
}
public function getLinesToBeCovered()
{
$class = get_class($this->getTestClass());
$method = $this->getTestMethod();
return \PHPUnit\Util\Test::getLinesToBeCovered($class, $method);
}
public function getLinesToBeUsed()
{
$class = get_class($this->getTestClass());
$method = $this->getTestMethod();
return \PHPUnit\Util\Test::getLinesToBeUsed($class, $method);
}
}