init
This commit is contained in:
84
vendor/codeception/base/src/Codeception/Test/Cept.php
vendored
Normal file
84
vendor/codeception/base/src/Codeception/Test/Cept.php
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
namespace Codeception\Test;
|
||||
|
||||
use Codeception\Exception\TestParseException;
|
||||
use Codeception\Lib\Parser;
|
||||
use Codeception\Lib\Console\Message;
|
||||
|
||||
/**
|
||||
* Executes tests delivered in Cept format.
|
||||
* Prepares metadata, parses test body on preload, and executes a test in `test` method.
|
||||
*/
|
||||
class Cept extends Test implements Interfaces\Plain, Interfaces\ScenarioDriven, Interfaces\Reported, Interfaces\Dependent
|
||||
{
|
||||
use Feature\ScenarioLoader;
|
||||
|
||||
/**
|
||||
* @var Parser
|
||||
*/
|
||||
protected $parser;
|
||||
|
||||
public function __construct($name, $file)
|
||||
{
|
||||
$metadata = new Metadata();
|
||||
$metadata->setName($name);
|
||||
$metadata->setFilename($file);
|
||||
$this->setMetadata($metadata);
|
||||
$this->createScenario();
|
||||
$this->parser = new Parser($this->getScenario(), $this->getMetadata());
|
||||
}
|
||||
|
||||
public function preload()
|
||||
{
|
||||
$this->getParser()->prepareToRun($this->getSourceCode());
|
||||
}
|
||||
|
||||
public function test()
|
||||
{
|
||||
$scenario = $this->getScenario();
|
||||
$testFile = $this->getMetadata()->getFilename();
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
try {
|
||||
require $testFile;
|
||||
} catch (\ParseError $e) {
|
||||
throw new TestParseException($testFile, $e->getMessage(), $e->getLine());
|
||||
}
|
||||
}
|
||||
|
||||
public function getSignature()
|
||||
{
|
||||
return $this->getMetadata()->getName() . 'Cept';
|
||||
}
|
||||
|
||||
public function toString()
|
||||
{
|
||||
return $this->getSignature() . ': ' . Message::ucfirst($this->getFeature());
|
||||
}
|
||||
|
||||
public function getSourceCode()
|
||||
{
|
||||
return file_get_contents($this->getFileName());
|
||||
}
|
||||
|
||||
public function getReportFields()
|
||||
{
|
||||
return [
|
||||
'name' => basename($this->getFileName(), 'Cept.php'),
|
||||
'file' => $this->getFileName(),
|
||||
'feature' => $this->getFeature()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Parser
|
||||
*/
|
||||
protected function getParser()
|
||||
{
|
||||
return $this->parser;
|
||||
}
|
||||
|
||||
public function fetchDependencies()
|
||||
{
|
||||
return $this->getMetadata()->getDependencies();
|
||||
}
|
||||
}
|
||||
218
vendor/codeception/base/src/Codeception/Test/Cest.php
vendored
Normal file
218
vendor/codeception/base/src/Codeception/Test/Cest.php
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
107
vendor/codeception/base/src/Codeception/Test/Descriptor.php
vendored
Normal file
107
vendor/codeception/base/src/Codeception/Test/Descriptor.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
namespace Codeception\Test;
|
||||
|
||||
use Codeception\Test\Interfaces\Descriptive;
|
||||
use Codeception\Test\Interfaces\Plain;
|
||||
use Codeception\Util\ReflectionHelper;
|
||||
|
||||
class Descriptor
|
||||
{
|
||||
/**
|
||||
* Provides a test name which can be located by
|
||||
*
|
||||
* @param \PHPUnit\Framework\SelfDescribing $testCase
|
||||
* @return string
|
||||
*/
|
||||
public static function getTestSignature(\PHPUnit\Framework\SelfDescribing $testCase)
|
||||
{
|
||||
if ($testCase instanceof Descriptive) {
|
||||
return $testCase->getSignature();
|
||||
}
|
||||
if ($testCase instanceof \PHPUnit\Framework\TestCase) {
|
||||
return get_class($testCase) . ':' . $testCase->getName(false);
|
||||
}
|
||||
return $testCase->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a test name which is unique for individual iterations of tests using examples
|
||||
*
|
||||
* @param \PHPUnit\Framework\SelfDescribing $testCase
|
||||
* @return string
|
||||
*/
|
||||
public static function getTestSignatureUnique(\PHPUnit\Framework\SelfDescribing $testCase)
|
||||
{
|
||||
$example = null;
|
||||
|
||||
if (method_exists($testCase, 'getMetaData')
|
||||
&& $example = $testCase->getMetadata()->getCurrent('example')
|
||||
) {
|
||||
$example = ':' . substr(sha1(json_encode($example)), 0, 7);
|
||||
}
|
||||
|
||||
return self::getTestSignature($testCase) . $example;
|
||||
}
|
||||
|
||||
public static function getTestAsString(\PHPUnit\Framework\SelfDescribing $testCase)
|
||||
{
|
||||
if ($testCase instanceof \PHPUnit\Framework\TestCase) {
|
||||
$text = $testCase->getName();
|
||||
$text = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\\1 \\2', $text);
|
||||
$text = preg_replace('/([a-z\d])([A-Z])/', '\\1 \\2', $text);
|
||||
$text = preg_replace('/^test /', '', $text);
|
||||
$text = ucfirst(strtolower($text));
|
||||
$text = str_replace(['::', 'with data set'], [':', '|'], $text);
|
||||
return ReflectionHelper::getClassShortName($testCase) . ': ' . $text;
|
||||
}
|
||||
|
||||
return $testCase->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a test file name relative to Codeception root
|
||||
*
|
||||
* @param \PHPUnit\Framework\SelfDescribing $testCase
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getTestFileName(\PHPUnit\Framework\SelfDescribing $testCase)
|
||||
{
|
||||
if ($testCase instanceof Descriptive) {
|
||||
return codecept_relative_path(realpath($testCase->getFileName()));
|
||||
}
|
||||
return (new \ReflectionClass($testCase))->getFileName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \PHPUnit\Framework\SelfDescribing $testCase
|
||||
* @return mixed|string
|
||||
*/
|
||||
public static function getTestFullName(\PHPUnit\Framework\SelfDescribing $testCase)
|
||||
{
|
||||
if ($testCase instanceof Plain) {
|
||||
return self::getTestFileName($testCase);
|
||||
}
|
||||
if ($testCase instanceof Descriptive) {
|
||||
$signature = $testCase->getSignature(); // cut everything before ":" from signature
|
||||
return self::getTestFileName($testCase) . ':' . preg_replace('~^(.*?):~', '', $signature);
|
||||
}
|
||||
if ($testCase instanceof \PHPUnit\Framework\TestCase) {
|
||||
return self::getTestFileName($testCase) . ':' . $testCase->getName(false);
|
||||
}
|
||||
return self::getTestFileName($testCase) . ':' . $testCase->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a test data set index
|
||||
*
|
||||
* @param \PHPUnit\Framework\SelfDescribing $testCase
|
||||
* @return int|null
|
||||
*/
|
||||
public static function getTestDataSetIndex(\PHPUnit\Framework\SelfDescribing $testCase)
|
||||
{
|
||||
if ($testCase instanceof Descriptive) {
|
||||
return $testCase->getMetadata()->getIndex();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
22
vendor/codeception/base/src/Codeception/Test/Feature/AssertionCounter.php
vendored
Normal file
22
vendor/codeception/base/src/Codeception/Test/Feature/AssertionCounter.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Feature;
|
||||
|
||||
trait AssertionCounter
|
||||
{
|
||||
protected $numAssertions = 0;
|
||||
|
||||
public function getNumAssertions()
|
||||
{
|
||||
return $this->numAssertions;
|
||||
}
|
||||
|
||||
protected function assertionCounterStart()
|
||||
{
|
||||
\PHPUnit\Framework\Assert::resetCount();
|
||||
}
|
||||
|
||||
protected function assertionCounterEnd()
|
||||
{
|
||||
$this->numAssertions = \PHPUnit\Framework\Assert::getCount();
|
||||
}
|
||||
}
|
||||
46
vendor/codeception/base/src/Codeception/Test/Feature/CodeCoverage.php
vendored
Normal file
46
vendor/codeception/base/src/Codeception/Test/Feature/CodeCoverage.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Feature;
|
||||
|
||||
use Codeception\Test\Descriptor;
|
||||
use Codeception\Test\Interfaces\StrictCoverage;
|
||||
|
||||
trait CodeCoverage
|
||||
{
|
||||
/**
|
||||
* @return \PHPUnit\Framework\TestResult
|
||||
*/
|
||||
abstract public function getTestResultObject();
|
||||
|
||||
public function codeCoverageStart()
|
||||
{
|
||||
$codeCoverage = $this->getTestResultObject()->getCodeCoverage();
|
||||
if (!$codeCoverage) {
|
||||
return;
|
||||
}
|
||||
$codeCoverage->start(Descriptor::getTestSignature($this));
|
||||
}
|
||||
|
||||
public function codeCoverageEnd($status, $time)
|
||||
{
|
||||
$codeCoverage = $this->getTestResultObject()->getCodeCoverage();
|
||||
if (!$codeCoverage) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this instanceof StrictCoverage) {
|
||||
$linesToBeCovered = $this->getLinesToBeCovered();
|
||||
$linesToBeUsed = $this->getLinesToBeUsed();
|
||||
} else {
|
||||
$linesToBeCovered = [];
|
||||
$linesToBeUsed = [];
|
||||
}
|
||||
|
||||
try {
|
||||
$codeCoverage->stop(true, $linesToBeCovered, $linesToBeUsed);
|
||||
} catch (\PHP_CodeCoverage_Exception $cce) {
|
||||
if ($status === \Codeception\Test\Test::STATUS_OK) {
|
||||
$this->getTestResultObject()->addError($this, $cce, $time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
26
vendor/codeception/base/src/Codeception/Test/Feature/ErrorLogger.php
vendored
Normal file
26
vendor/codeception/base/src/Codeception/Test/Feature/ErrorLogger.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Feature;
|
||||
|
||||
use Codeception\Test\Test as CodeceptionTest;
|
||||
|
||||
trait ErrorLogger
|
||||
{
|
||||
/**
|
||||
* @return \PHPUnit\Framework\TestResult
|
||||
*/
|
||||
abstract public function getTestResultObject();
|
||||
|
||||
public function errorLoggerEnd($status, $time, $exception = null)
|
||||
{
|
||||
if (!$exception) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($status === CodeceptionTest::STATUS_ERROR) {
|
||||
$this->getTestResultObject()->addError($this, $exception, $time);
|
||||
}
|
||||
if ($status === CodeceptionTest::STATUS_FAIL) {
|
||||
$this->getTestResultObject()->addFailure($this, $exception, $time);
|
||||
}
|
||||
}
|
||||
}
|
||||
37
vendor/codeception/base/src/Codeception/Test/Feature/IgnoreIfMetadataBlocked.php
vendored
Normal file
37
vendor/codeception/base/src/Codeception/Test/Feature/IgnoreIfMetadataBlocked.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Feature;
|
||||
|
||||
use Codeception\Test\Metadata;
|
||||
|
||||
trait IgnoreIfMetadataBlocked
|
||||
{
|
||||
/**
|
||||
* @return Metadata
|
||||
*/
|
||||
abstract protected function getMetadata();
|
||||
|
||||
abstract protected function ignore($ignored);
|
||||
|
||||
/**
|
||||
* @return \PHPUnit\Framework\TestResult
|
||||
*/
|
||||
abstract protected function getTestResultObject();
|
||||
|
||||
protected function ignoreIfMetadataBlockedStart()
|
||||
{
|
||||
if (!$this->getMetadata()->isBlocked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->ignore(true);
|
||||
|
||||
if ($this->getMetadata()->getSkip() !== null) {
|
||||
$this->getTestResultObject()->addFailure($this, new \PHPUnit\Framework\SkippedTestError((string)$this->getMetadata()->getSkip()), 0);
|
||||
return;
|
||||
}
|
||||
if ($this->getMetadata()->getIncomplete() !== null) {
|
||||
$this->getTestResultObject()->addFailure($this, new \PHPUnit\Framework\IncompleteTestError((string)$this->getMetadata()->getIncomplete()), 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
vendor/codeception/base/src/Codeception/Test/Feature/MetadataCollector.php
vendored
Normal file
32
vendor/codeception/base/src/Codeception/Test/Feature/MetadataCollector.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Feature;
|
||||
|
||||
use Codeception\Test\Metadata;
|
||||
|
||||
trait MetadataCollector
|
||||
{
|
||||
/**
|
||||
* @var Metadata
|
||||
*/
|
||||
private $metadata;
|
||||
|
||||
protected function setMetadata(Metadata $metadata)
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
}
|
||||
|
||||
public function getMetadata()
|
||||
{
|
||||
return $this->metadata;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->getMetadata()->getName();
|
||||
}
|
||||
|
||||
public function getFileName()
|
||||
{
|
||||
return $this->getMetadata()->getFilename();
|
||||
}
|
||||
}
|
||||
54
vendor/codeception/base/src/Codeception/Test/Feature/ScenarioLoader.php
vendored
Normal file
54
vendor/codeception/base/src/Codeception/Test/Feature/ScenarioLoader.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Feature;
|
||||
|
||||
use Codeception\Lib\Parser;
|
||||
use Codeception\Scenario;
|
||||
use Codeception\Test\Metadata;
|
||||
|
||||
trait ScenarioLoader
|
||||
{
|
||||
/**
|
||||
* @var Scenario
|
||||
*/
|
||||
private $scenario;
|
||||
|
||||
/**
|
||||
* @return Metadata
|
||||
*/
|
||||
abstract public function getMetadata();
|
||||
|
||||
protected function createScenario()
|
||||
{
|
||||
$this->scenario = new Scenario($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Scenario
|
||||
*/
|
||||
public function getScenario()
|
||||
{
|
||||
return $this->scenario;
|
||||
}
|
||||
|
||||
public function getFeature()
|
||||
{
|
||||
return $this->getScenario()->getFeature();
|
||||
}
|
||||
|
||||
public function getScenarioText($format = 'text')
|
||||
{
|
||||
$code = $this->getSourceCode();
|
||||
$this->getParser()->parseFeature($code);
|
||||
$this->getParser()->parseSteps($code);
|
||||
if ($format == 'html') {
|
||||
return $this->getScenario()->getHtml();
|
||||
}
|
||||
return $this->getScenario()->getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Parser
|
||||
*/
|
||||
abstract protected function getParser();
|
||||
abstract public function getSourceCode();
|
||||
}
|
||||
221
vendor/codeception/base/src/Codeception/Test/Gherkin.php
vendored
Normal file
221
vendor/codeception/base/src/Codeception/Test/Gherkin.php
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
namespace Codeception\Test;
|
||||
|
||||
use Behat\Gherkin\Node\FeatureNode;
|
||||
use Behat\Gherkin\Node\ScenarioNode;
|
||||
use Behat\Gherkin\Node\ScenarioInterface;
|
||||
use Behat\Gherkin\Node\StepNode;
|
||||
use Behat\Gherkin\Node\TableNode;
|
||||
use Codeception\Lib\Di;
|
||||
use Codeception\Lib\Generator\GherkinSnippets;
|
||||
use Codeception\Scenario;
|
||||
use Codeception\Step\Comment;
|
||||
use Codeception\Step\Meta;
|
||||
use Codeception\Test\Interfaces\Reported;
|
||||
use Codeception\Test\Interfaces\ScenarioDriven;
|
||||
|
||||
class Gherkin extends Test implements ScenarioDriven, Reported
|
||||
{
|
||||
protected $steps = [];
|
||||
|
||||
/**
|
||||
* @var FeatureNode
|
||||
*/
|
||||
protected $featureNode;
|
||||
|
||||
/**
|
||||
* @var ScenarioNode
|
||||
*/
|
||||
protected $scenarioNode;
|
||||
|
||||
/**
|
||||
* @var Scenario
|
||||
*/
|
||||
protected $scenario;
|
||||
|
||||
public function __construct(FeatureNode $featureNode, ScenarioInterface $scenarioNode, $steps = [])
|
||||
{
|
||||
$this->featureNode = $featureNode;
|
||||
$this->scenarioNode = $scenarioNode;
|
||||
$this->steps = $steps;
|
||||
$this->setMetadata(new Metadata());
|
||||
$this->scenario = new Scenario($this);
|
||||
$this->getMetadata()->setName($featureNode->getTitle());
|
||||
$this->getMetadata()->setFeature($scenarioNode->getTitle());
|
||||
$this->getMetadata()->setFilename($featureNode->getFile());
|
||||
}
|
||||
|
||||
public function preload()
|
||||
{
|
||||
$this->getMetadata()->setGroups($this->featureNode->getTags());
|
||||
$this->getMetadata()->setGroups($this->scenarioNode->getTags());
|
||||
$this->scenario->setMetaStep(null);
|
||||
|
||||
if ($background = $this->featureNode->getBackground()) {
|
||||
foreach ($background->getSteps() as $step) {
|
||||
$this->validateStep($step);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->scenarioNode->getSteps() as $step) {
|
||||
$this->validateStep($step);
|
||||
}
|
||||
if ($this->getMetadata()->getIncomplete()) {
|
||||
$this->getMetadata()->setIncomplete($this->getMetadata()->getIncomplete() . "\nRun gherkin:snippets to define missing steps");
|
||||
}
|
||||
}
|
||||
|
||||
public function getSignature()
|
||||
{
|
||||
return basename($this->getFileName(), '.feature') . ':' . $this->getFeature();
|
||||
}
|
||||
|
||||
public function test()
|
||||
{
|
||||
$this->makeContexts();
|
||||
$description = explode("\n", $this->featureNode->getDescription());
|
||||
foreach ($description as $line) {
|
||||
$this->getScenario()->runStep(new Comment($line));
|
||||
}
|
||||
|
||||
if ($background = $this->featureNode->getBackground()) {
|
||||
foreach ($background->getSteps() as $step) {
|
||||
$this->runStep($step);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->scenarioNode->getSteps() as $step) {
|
||||
$this->runStep($step);
|
||||
}
|
||||
}
|
||||
|
||||
protected function validateStep(StepNode $stepNode)
|
||||
{
|
||||
$stepText = $stepNode->getText();
|
||||
if (GherkinSnippets::stepHasPyStringArgument($stepNode)) {
|
||||
$stepText .= ' ""';
|
||||
}
|
||||
foreach ($this->steps as $pattern => $context) {
|
||||
$res = preg_match($pattern, $stepText);
|
||||
if (!$res) {
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
$incomplete = $this->getMetadata()->getIncomplete();
|
||||
$this->getMetadata()->setIncomplete("$incomplete\nStep definition for `$stepText` not found in contexts");
|
||||
}
|
||||
|
||||
protected function runStep(StepNode $stepNode)
|
||||
{
|
||||
$params = [];
|
||||
if ($stepNode->hasArguments()) {
|
||||
$args = $stepNode->getArguments();
|
||||
$table = $args[0];
|
||||
if ($table instanceof TableNode) {
|
||||
$params = [$table->getTableAsString()];
|
||||
}
|
||||
}
|
||||
$meta = new Meta($stepNode->getText(), $params);
|
||||
$meta->setPrefix($stepNode->getKeyword());
|
||||
$this->scenario->setMetaStep($meta); // enable metastep
|
||||
$stepText = $stepNode->getText();
|
||||
$hasPyStringArg = GherkinSnippets::stepHasPyStringArgument($stepNode);
|
||||
if ($hasPyStringArg) {
|
||||
// pretend it is inline argument
|
||||
$stepText .= ' ""';
|
||||
}
|
||||
$this->getScenario()->comment(null); // make metastep to be printed even if no steps in it
|
||||
foreach ($this->steps as $pattern => $context) {
|
||||
$matches = [];
|
||||
if (!preg_match($pattern, $stepText, $matches)) {
|
||||
continue;
|
||||
}
|
||||
array_shift($matches);
|
||||
if ($hasPyStringArg) {
|
||||
// get rid off last fake argument
|
||||
array_pop($matches);
|
||||
}
|
||||
if ($stepNode->hasArguments()) {
|
||||
$matches = array_merge($matches, $stepNode->getArguments());
|
||||
}
|
||||
call_user_func_array($context, $matches); // execute the step
|
||||
break;
|
||||
}
|
||||
$this->scenario->setMetaStep(null); // disable metastep
|
||||
}
|
||||
|
||||
protected function makeContexts()
|
||||
{
|
||||
/** @var $di Di **/
|
||||
$di = $this->getMetadata()->getService('di');
|
||||
$di->set($this->getScenario());
|
||||
|
||||
$actorClass = $this->getMetadata()->getCurrent('actor');
|
||||
if ($actorClass) {
|
||||
$di->set(new $actorClass($this->getScenario()));
|
||||
}
|
||||
|
||||
foreach ($this->steps as $pattern => $step) {
|
||||
$di->instantiate($step[0]);
|
||||
$this->steps[$pattern][0] = $di->get($step[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public function toString()
|
||||
{
|
||||
return $this->featureNode->getTitle() . ': ' . $this->getFeature();
|
||||
}
|
||||
|
||||
public function getFeature()
|
||||
{
|
||||
return $this->getMetadata()->getFeature();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Codeception\Scenario
|
||||
*/
|
||||
public function getScenario()
|
||||
{
|
||||
return $this->scenario;
|
||||
}
|
||||
|
||||
public function getScenarioText($format = 'text')
|
||||
{
|
||||
return file_get_contents($this->getFileName());
|
||||
}
|
||||
|
||||
public function getSourceCode()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ScenarioNode
|
||||
*/
|
||||
public function getScenarioNode()
|
||||
{
|
||||
return $this->scenarioNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FeatureNode
|
||||
*/
|
||||
public function getFeatureNode()
|
||||
{
|
||||
return $this->featureNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Field values for XML/JSON/TAP reports
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getReportFields()
|
||||
{
|
||||
return [
|
||||
'file' => $this->getFileName(),
|
||||
'name' => $this->toString(),
|
||||
'feature' => $this->getFeature()
|
||||
];
|
||||
}
|
||||
}
|
||||
7
vendor/codeception/base/src/Codeception/Test/Interfaces/Dependent.php
vendored
Normal file
7
vendor/codeception/base/src/Codeception/Test/Interfaces/Dependent.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Interfaces;
|
||||
|
||||
interface Dependent
|
||||
{
|
||||
public function fetchDependencies();
|
||||
}
|
||||
9
vendor/codeception/base/src/Codeception/Test/Interfaces/Descriptive.php
vendored
Normal file
9
vendor/codeception/base/src/Codeception/Test/Interfaces/Descriptive.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Interfaces;
|
||||
|
||||
interface Descriptive extends \PHPUnit\Framework\SelfDescribing
|
||||
{
|
||||
public function getFileName();
|
||||
|
||||
public function getSignature();
|
||||
}
|
||||
9
vendor/codeception/base/src/Codeception/Test/Interfaces/Plain.php
vendored
Normal file
9
vendor/codeception/base/src/Codeception/Test/Interfaces/Plain.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Interfaces;
|
||||
|
||||
/**
|
||||
* TestCases that do not follow OOP
|
||||
*/
|
||||
interface Plain
|
||||
{
|
||||
}
|
||||
12
vendor/codeception/base/src/Codeception/Test/Interfaces/Reported.php
vendored
Normal file
12
vendor/codeception/base/src/Codeception/Test/Interfaces/Reported.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Interfaces;
|
||||
|
||||
interface Reported
|
||||
{
|
||||
/**
|
||||
* Field values for XML/JSON/TAP reports
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getReportFields();
|
||||
}
|
||||
18
vendor/codeception/base/src/Codeception/Test/Interfaces/ScenarioDriven.php
vendored
Normal file
18
vendor/codeception/base/src/Codeception/Test/Interfaces/ScenarioDriven.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Interfaces;
|
||||
|
||||
interface ScenarioDriven
|
||||
{
|
||||
public function getFeature();
|
||||
|
||||
/**
|
||||
* @return \Codeception\Scenario
|
||||
*/
|
||||
public function getScenario();
|
||||
|
||||
public function getScenarioText($format = 'text');
|
||||
|
||||
public function preload();
|
||||
|
||||
public function getSourceCode();
|
||||
}
|
||||
10
vendor/codeception/base/src/Codeception/Test/Interfaces/StrictCoverage.php
vendored
Normal file
10
vendor/codeception/base/src/Codeception/Test/Interfaces/StrictCoverage.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Codeception\Test\Interfaces;
|
||||
|
||||
interface StrictCoverage
|
||||
{
|
||||
public function getLinesToBeCovered();
|
||||
|
||||
public function getLinesToBeUsed();
|
||||
}
|
||||
144
vendor/codeception/base/src/Codeception/Test/Loader.php
vendored
Normal file
144
vendor/codeception/base/src/Codeception/Test/Loader.php
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
namespace Codeception\Test;
|
||||
|
||||
use Codeception\Test\Loader\Cept as CeptLoader;
|
||||
use Codeception\Test\Loader\Cest as CestLoader;
|
||||
use Codeception\Test\Loader\Unit as UnitLoader;
|
||||
use Codeception\Test\Loader\Gherkin as GherkinLoader;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
/**
|
||||
* Loads all Codeception supported test formats from a directory.
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $testLoader = new \Codeception\TestLoader('tests/unit');
|
||||
* $testLoader->loadTests();
|
||||
* $tests = $testLoader->getTests();
|
||||
* ?>
|
||||
* ```
|
||||
* You can load specific file
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $testLoader = new \Codeception\TestLoader('tests/unit');
|
||||
* $testLoader->loadTest('UserTest.php');
|
||||
* $testLoader->loadTest('PostTest.php');
|
||||
* $tests = $testLoader->getTests();
|
||||
* ?>
|
||||
* ```
|
||||
* or a subdirectory
|
||||
*
|
||||
* ``` php
|
||||
* <?php
|
||||
* $testLoader = new \Codeception\TestLoader('tests/unit');
|
||||
* $testLoader->loadTest('models'); // all tests from tests/unit/models
|
||||
* $tests = $testLoader->getTests();
|
||||
* ?>
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
class Loader
|
||||
{
|
||||
protected $formats = [];
|
||||
protected $tests = [];
|
||||
protected $path;
|
||||
|
||||
public function __construct(array $suiteSettings)
|
||||
{
|
||||
$this->path = $suiteSettings['path'];
|
||||
$this->formats = [
|
||||
new CeptLoader(),
|
||||
new CestLoader(),
|
||||
new UnitLoader(),
|
||||
new GherkinLoader($suiteSettings)
|
||||
];
|
||||
if (isset($suiteSettings['formats'])) {
|
||||
foreach ($suiteSettings['formats'] as $format) {
|
||||
$this->formats[] = new $format($suiteSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getTests()
|
||||
{
|
||||
return $this->tests;
|
||||
}
|
||||
|
||||
protected function relativeName($file)
|
||||
{
|
||||
return str_replace([$this->path, '\\'], ['', '/'], $file);
|
||||
}
|
||||
|
||||
protected function findPath($path)
|
||||
{
|
||||
if (!file_exists($path)
|
||||
&& substr($path, -strlen('.php')) !== '.php'
|
||||
&& file_exists($newPath = $path . '.php')
|
||||
) {
|
||||
return $newPath;
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
protected function makePath($originalPath)
|
||||
{
|
||||
$path = $this->path . $this->relativeName($originalPath);
|
||||
|
||||
if (file_exists($newPath = $this->findPath($path))
|
||||
|| file_exists($newPath = $this->findPath(getcwd() . "/{$originalPath}"))
|
||||
) {
|
||||
$path = $newPath;
|
||||
}
|
||||
|
||||
if (!file_exists($path)) {
|
||||
throw new \Exception("File or path $originalPath not found");
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
public function loadTest($path)
|
||||
{
|
||||
$path = $this->makePath($path);
|
||||
|
||||
foreach ($this->formats as $format) {
|
||||
/** @var $format Loader **/
|
||||
if (preg_match($format->getPattern(), $path)) {
|
||||
$format->loadTests($path);
|
||||
$this->tests = $format->getTests();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_dir($path)) {
|
||||
$currentPath = $this->path;
|
||||
$this->path = $path;
|
||||
$this->loadTests();
|
||||
$this->path = $currentPath;
|
||||
return;
|
||||
}
|
||||
throw new \Exception('Test format not supported. Please, check you use the right suffix. Available filetypes: Cept, Cest, Test');
|
||||
}
|
||||
|
||||
public function loadTests($fileName = null)
|
||||
{
|
||||
if ($fileName) {
|
||||
return $this->loadTest($fileName);
|
||||
}
|
||||
|
||||
$finder = Finder::create()->files()->sortByName()->in($this->path)->followLinks();
|
||||
|
||||
foreach ($this->formats as $format) {
|
||||
/** @var $format Loader **/
|
||||
$formatFinder = clone($finder);
|
||||
$testFiles = $formatFinder->name($format->getPattern());
|
||||
foreach ($testFiles as $test) {
|
||||
$pathname = str_replace(["//", "\\\\"], ["/", "\\"], $test->getPathname());
|
||||
$format->loadTests($pathname);
|
||||
}
|
||||
$this->tests = array_merge($this->tests, $format->getTests());
|
||||
}
|
||||
}
|
||||
}
|
||||
29
vendor/codeception/base/src/Codeception/Test/Loader/Cept.php
vendored
Normal file
29
vendor/codeception/base/src/Codeception/Test/Loader/Cept.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Loader;
|
||||
|
||||
use Codeception\Lib\Parser;
|
||||
use Codeception\Test\Cept as CeptFormat;
|
||||
|
||||
class Cept implements LoaderInterface
|
||||
{
|
||||
protected $tests = [];
|
||||
|
||||
public function getPattern()
|
||||
{
|
||||
return '~Cept\.php$~';
|
||||
}
|
||||
|
||||
function loadTests($file)
|
||||
{
|
||||
Parser::validate($file);
|
||||
$name = basename($file, 'Cept.php');
|
||||
|
||||
$cept = new CeptFormat($name, $file);
|
||||
$this->tests[] = $cept;
|
||||
}
|
||||
|
||||
public function getTests()
|
||||
{
|
||||
return $this->tests;
|
||||
}
|
||||
}
|
||||
102
vendor/codeception/base/src/Codeception/Test/Loader/Cest.php
vendored
Normal file
102
vendor/codeception/base/src/Codeception/Test/Loader/Cest.php
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Loader;
|
||||
|
||||
use Codeception\Exception\TestParseException;
|
||||
use Codeception\Lib\Parser;
|
||||
use Codeception\Test\Cest as CestFormat;
|
||||
use Codeception\Util\Annotation;
|
||||
use Codeception\Util\ReflectionHelper;
|
||||
|
||||
class Cest implements LoaderInterface
|
||||
{
|
||||
protected $tests = [];
|
||||
|
||||
public function getTests()
|
||||
{
|
||||
return $this->tests;
|
||||
}
|
||||
|
||||
public function getPattern()
|
||||
{
|
||||
return '~Cest\.php$~';
|
||||
}
|
||||
|
||||
public function loadTests($file)
|
||||
{
|
||||
Parser::load($file);
|
||||
$testClasses = Parser::getClassesFromFile($file);
|
||||
|
||||
foreach ($testClasses as $testClass) {
|
||||
if (substr($testClass, -strlen('Cest')) !== 'Cest') {
|
||||
continue;
|
||||
}
|
||||
if (!(new \ReflectionClass($testClass))->isInstantiable()) {
|
||||
continue;
|
||||
}
|
||||
$unit = new $testClass;
|
||||
|
||||
$methods = get_class_methods($testClass);
|
||||
foreach ($methods as $method) {
|
||||
if (strpos($method, '_') === 0) {
|
||||
continue;
|
||||
}
|
||||
$examples = [];
|
||||
|
||||
// example Annotation
|
||||
$rawExamples = Annotation::forMethod($unit, $method)->fetchAll('example');
|
||||
if (count($rawExamples)) {
|
||||
$examples = array_map(
|
||||
function ($v) {
|
||||
return Annotation::arrayValue($v);
|
||||
},
|
||||
$rawExamples
|
||||
);
|
||||
}
|
||||
|
||||
// dataProvider Annotation
|
||||
$dataMethod = Annotation::forMethod($testClass, $method)->fetch('dataProvider');
|
||||
// lowercase for back compatible
|
||||
if (empty($dataMethod)) {
|
||||
$dataMethod = Annotation::forMethod($testClass, $method)->fetch('dataprovider');
|
||||
}
|
||||
|
||||
if (!empty($dataMethod)) {
|
||||
try {
|
||||
$data = ReflectionHelper::invokePrivateMethod($unit, $dataMethod);
|
||||
// allow to mix example and dataprovider annotations
|
||||
$examples = array_merge($examples, $data);
|
||||
} catch (\ReflectionException $e) {
|
||||
throw new TestParseException(
|
||||
$file,
|
||||
"DataProvider '$dataMethod' for $testClass->$method is invalid or not callable.\n" .
|
||||
"Make sure that the dataprovider exist within the test class."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($examples)) {
|
||||
$dataProvider = new \PHPUnit\Framework\DataProviderTestSuite();
|
||||
$index = 0;
|
||||
foreach ($examples as $k => $example) {
|
||||
if ($example === null) {
|
||||
throw new TestParseException(
|
||||
$file,
|
||||
"Example for $testClass->$method contains invalid data:\n" .
|
||||
$rawExamples[$k] . "\n" .
|
||||
"Make sure this is a valid JSON (Hint: \"-char for strings) or a single-line annotation in Doctrine-style"
|
||||
);
|
||||
}
|
||||
$test = new CestFormat($unit, $method, $file);
|
||||
$test->getMetadata()->setCurrent(['example' => $example]);
|
||||
$test->getMetadata()->setIndex($index);
|
||||
$dataProvider->addTest($test);
|
||||
$index++;
|
||||
}
|
||||
$this->tests[] = $dataProvider;
|
||||
continue;
|
||||
}
|
||||
$this->tests[] = new CestFormat($unit, $method, $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
198
vendor/codeception/base/src/Codeception/Test/Loader/Gherkin.php
vendored
Normal file
198
vendor/codeception/base/src/Codeception/Test/Loader/Gherkin.php
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Loader;
|
||||
|
||||
use Behat\Gherkin\Filter\RoleFilter;
|
||||
use Behat\Gherkin\Keywords\ArrayKeywords as GherkinKeywords;
|
||||
use Behat\Gherkin\Lexer as GherkinLexer;
|
||||
use Behat\Gherkin\Node\ExampleNode;
|
||||
use Behat\Gherkin\Node\OutlineNode;
|
||||
use Behat\Gherkin\Node\ScenarioInterface;
|
||||
use Behat\Gherkin\Node\ScenarioNode;
|
||||
use Behat\Gherkin\Parser as GherkinParser;
|
||||
use Codeception\Configuration;
|
||||
use Codeception\Exception\ParseException;
|
||||
use Codeception\Exception\TestParseException;
|
||||
use Codeception\Test\Gherkin as GherkinFormat;
|
||||
use Codeception\Util\Annotation;
|
||||
|
||||
class Gherkin implements LoaderInterface
|
||||
{
|
||||
protected static $defaultSettings = [
|
||||
'namespace' => '',
|
||||
'actor' => '',
|
||||
'gherkin' => [
|
||||
'contexts' => [
|
||||
'default' => [],
|
||||
'tag' => [],
|
||||
'role' => []
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
protected $tests = [];
|
||||
|
||||
/**
|
||||
* @var GherkinParser
|
||||
*/
|
||||
protected $parser;
|
||||
|
||||
protected $settings = [];
|
||||
|
||||
protected $steps = [];
|
||||
|
||||
public function __construct($settings = [])
|
||||
{
|
||||
$this->settings = Configuration::mergeConfigs(self::$defaultSettings, $settings);
|
||||
if (!class_exists('Behat\Gherkin\Keywords\ArrayKeywords')) {
|
||||
throw new TestParseException('Feature file can only be parsed with Behat\Gherkin library. Please install `behat/gherkin` with Composer');
|
||||
}
|
||||
$gherkin = new \ReflectionClass('Behat\Gherkin\Gherkin');
|
||||
$gherkinClassPath = dirname($gherkin->getFileName());
|
||||
$i18n = require $gherkinClassPath . '/../../../i18n.php';
|
||||
$keywords = new GherkinKeywords($i18n);
|
||||
$lexer = new GherkinLexer($keywords);
|
||||
$this->parser = new GherkinParser($lexer);
|
||||
$this->fetchGherkinSteps();
|
||||
}
|
||||
|
||||
protected function fetchGherkinSteps()
|
||||
{
|
||||
$contexts = $this->settings['gherkin']['contexts'];
|
||||
|
||||
foreach ($contexts['tag'] as $tag => $tagContexts) {
|
||||
$this->addSteps($tagContexts, "tag:$tag");
|
||||
}
|
||||
foreach ($contexts['role'] as $role => $roleContexts) {
|
||||
$this->addSteps($roleContexts, "role:$role");
|
||||
}
|
||||
|
||||
if (empty($this->steps) && empty($contexts['default']) && $this->settings['actor']) { // if no context is set, actor to be a context
|
||||
$actorContext = $this->settings['namespace']
|
||||
? rtrim($this->settings['namespace'] . '\\' . $this->settings['actor'], '\\')
|
||||
: $this->settings['actor'];
|
||||
if ($actorContext) {
|
||||
$contexts['default'][] = $actorContext;
|
||||
}
|
||||
}
|
||||
|
||||
$this->addSteps($contexts['default']);
|
||||
}
|
||||
|
||||
protected function addSteps(array $contexts, $group = 'default')
|
||||
{
|
||||
$this->steps[$group] = [];
|
||||
foreach ($contexts as $context) {
|
||||
$methods = get_class_methods($context);
|
||||
if (!$methods) {
|
||||
continue;
|
||||
}
|
||||
foreach ($methods as $method) {
|
||||
$annotation = Annotation::forMethod($context, $method);
|
||||
foreach (['Given', 'When', 'Then'] as $type) {
|
||||
$patterns = $annotation->fetchAll($type);
|
||||
foreach ($patterns as $pattern) {
|
||||
if (!$pattern) {
|
||||
continue;
|
||||
}
|
||||
$this->validatePattern($pattern);
|
||||
$pattern = $this->makePlaceholderPattern($pattern);
|
||||
$this->steps[$group][$pattern] = [$context, $method];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function makePlaceholderPattern($pattern)
|
||||
{
|
||||
if (isset($this->settings['describe_steps'])) {
|
||||
return $pattern;
|
||||
}
|
||||
if (strpos($pattern, '/') !== 0) {
|
||||
$pattern = preg_quote($pattern);
|
||||
|
||||
$pattern = preg_replace('~(\w+)\/(\w+)~', '(?:$1|$2)', $pattern); // or
|
||||
$pattern = preg_replace('~\\\\\((\w)\\\\\)~', '$1?', $pattern); // (s)
|
||||
|
||||
$replacePattern = sprintf(
|
||||
'(?|\"%s\"|%s)',
|
||||
"((?|[^\"\\\\\\]|\\\\\\.)*?)", // matching escaped string in ""
|
||||
'[\D]{0,1}([\d\,\.]+)[\D]{0,1}'
|
||||
); // or matching numbers with optional $ or € chars
|
||||
|
||||
// params converting from :param to match 11 and "aaa" and "aaa\"aaa"
|
||||
$pattern = preg_replace('~"?\\\:(\w+)"?~', $replacePattern, $pattern);
|
||||
$pattern = "/^$pattern$/u";
|
||||
// validating this pattern is slow, so we skip it now
|
||||
}
|
||||
return $pattern;
|
||||
}
|
||||
|
||||
private function validatePattern($pattern)
|
||||
{
|
||||
if (strpos($pattern, '/') !== 0) {
|
||||
return; // not a user-regex but a string with placeholder
|
||||
}
|
||||
if (@preg_match($pattern, ' ') === false) {
|
||||
throw new ParseException("Loading Gherkin step with regex\n \n$pattern\n \nfailed. This regular expression is invalid.");
|
||||
}
|
||||
}
|
||||
|
||||
public function loadTests($filename)
|
||||
{
|
||||
$featureNode = $this->parser->parse(file_get_contents($filename), $filename);
|
||||
|
||||
if (!$featureNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($featureNode->getScenarios() as $scenarioNode) {
|
||||
/** @var $scenarioNode ScenarioInterface **/
|
||||
$steps = $this->steps['default']; // load default context
|
||||
|
||||
foreach (array_merge($scenarioNode->getTags(), $featureNode->getTags()) as $tag) { // load tag contexts
|
||||
if (isset($this->steps["tag:$tag"])) {
|
||||
$steps = array_merge($steps, $this->steps["tag:$tag"]);
|
||||
}
|
||||
}
|
||||
|
||||
$roles = $this->settings['gherkin']['contexts']['role']; // load role contexts
|
||||
foreach ($roles as $role => $context) {
|
||||
$filter = new RoleFilter($role);
|
||||
if ($filter->isFeatureMatch($featureNode)) {
|
||||
$steps = array_merge($steps, $this->steps["role:$role"]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($scenarioNode instanceof OutlineNode) {
|
||||
foreach ($scenarioNode->getExamples() as $example) {
|
||||
/** @var $example ExampleNode **/
|
||||
$params = implode(', ', $example->getTokens());
|
||||
$exampleNode = new ScenarioNode($scenarioNode->getTitle() . " | $params", $scenarioNode->getTags(), $example->getSteps(), $example->getKeyword(), $example->getLine());
|
||||
$this->tests[] = new GherkinFormat($featureNode, $exampleNode, $steps);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$this->tests[] = new GherkinFormat($featureNode, $scenarioNode, $steps);
|
||||
}
|
||||
}
|
||||
|
||||
public function getTests()
|
||||
{
|
||||
return $this->tests;
|
||||
}
|
||||
|
||||
public function getPattern()
|
||||
{
|
||||
return '~\.feature$~';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSteps()
|
||||
{
|
||||
return $this->steps;
|
||||
}
|
||||
}
|
||||
11
vendor/codeception/base/src/Codeception/Test/Loader/LoaderInterface.php
vendored
Normal file
11
vendor/codeception/base/src/Codeception/Test/Loader/LoaderInterface.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Loader;
|
||||
|
||||
interface LoaderInterface
|
||||
{
|
||||
public function loadTests($filename);
|
||||
|
||||
public function getTests();
|
||||
|
||||
public function getPattern();
|
||||
}
|
||||
73
vendor/codeception/base/src/Codeception/Test/Loader/Unit.php
vendored
Normal file
73
vendor/codeception/base/src/Codeception/Test/Loader/Unit.php
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
namespace Codeception\Test\Loader;
|
||||
|
||||
use Codeception\Lib\Parser;
|
||||
use Codeception\Test\Descriptor;
|
||||
use Codeception\Test\Unit as UnitFormat;
|
||||
use Codeception\Util\Annotation;
|
||||
|
||||
class Unit implements LoaderInterface
|
||||
{
|
||||
protected $tests = [];
|
||||
|
||||
public function getPattern()
|
||||
{
|
||||
return '~Test\.php$~';
|
||||
}
|
||||
|
||||
public function loadTests($path)
|
||||
{
|
||||
Parser::load($path);
|
||||
$testClasses = Parser::getClassesFromFile($path);
|
||||
|
||||
foreach ($testClasses as $testClass) {
|
||||
$reflected = new \ReflectionClass($testClass);
|
||||
if (!$reflected->isInstantiable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($reflected->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
|
||||
$test = $this->createTestFromPhpUnitMethod($reflected, $method);
|
||||
if (!$test) {
|
||||
continue;
|
||||
}
|
||||
$this->tests[] = $test;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getTests()
|
||||
{
|
||||
return $this->tests;
|
||||
}
|
||||
|
||||
protected function createTestFromPhpUnitMethod(\ReflectionClass $class, \ReflectionMethod $method)
|
||||
{
|
||||
if (!\PHPUnit\Framework\TestSuite::isTestMethod($method)) {
|
||||
return;
|
||||
}
|
||||
$test = \PHPUnit\Framework\TestSuite::createTest($class, $method->name);
|
||||
|
||||
if ($test instanceof \PHPUnit\Framework\DataProviderTestSuite) {
|
||||
foreach ($test->tests() as $t) {
|
||||
$this->enhancePhpunitTest($t);
|
||||
}
|
||||
return $test;
|
||||
}
|
||||
|
||||
$this->enhancePhpunitTest($test);
|
||||
return $test;
|
||||
}
|
||||
|
||||
protected function enhancePhpunitTest(\PHPUnit\Framework\Test $test)
|
||||
{
|
||||
$className = get_class($test);
|
||||
$methodName = $test->getName(false);
|
||||
$dependencies = \PHPUnit\Util\Test::getDependencies($className, $methodName);
|
||||
$test->setDependencies($dependencies);
|
||||
if ($test instanceof UnitFormat) {
|
||||
$test->getMetadata()->setParamsFromAnnotations(Annotation::forMethod($test, $methodName)->raw());
|
||||
$test->getMetadata()->setFilename(Descriptor::getTestFileName($test));
|
||||
}
|
||||
}
|
||||
}
|
||||
262
vendor/codeception/base/src/Codeception/Test/Metadata.php
vendored
Normal file
262
vendor/codeception/base/src/Codeception/Test/Metadata.php
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
namespace Codeception\Test;
|
||||
|
||||
use Codeception\Exception\InjectionException;
|
||||
use Codeception\Util\Annotation;
|
||||
|
||||
class Metadata
|
||||
{
|
||||
protected $name;
|
||||
protected $filename;
|
||||
protected $feature;
|
||||
protected $index;
|
||||
|
||||
protected $params = [
|
||||
'env' => [],
|
||||
'group' => [],
|
||||
'depends' => [],
|
||||
'skip' => null,
|
||||
'incomplete' => null
|
||||
];
|
||||
|
||||
protected $current = [];
|
||||
protected $services = [];
|
||||
protected $reports = [];
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getEnv()
|
||||
{
|
||||
return $this->params['env'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getGroups()
|
||||
{
|
||||
return array_unique($this->params['group']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $groups
|
||||
*/
|
||||
public function setGroups($groups)
|
||||
{
|
||||
$this->params['group'] = array_merge($this->params['group'], $groups);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSkip()
|
||||
{
|
||||
return $this->params['skip'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $skip
|
||||
*/
|
||||
public function setSkip($skip)
|
||||
{
|
||||
$this->params['skip'] = $skip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIncomplete()
|
||||
{
|
||||
return $this->params['incomplete'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $incomplete
|
||||
*/
|
||||
public function setIncomplete($incomplete)
|
||||
{
|
||||
$this->params['incomplete'] = $incomplete;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCurrent($key = null)
|
||||
{
|
||||
if ($key) {
|
||||
if (isset($this->current[$key])) {
|
||||
return $this->current[$key];
|
||||
}
|
||||
if ($key === 'name') {
|
||||
return $this->getName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->current;
|
||||
}
|
||||
|
||||
public function setCurrent(array $currents)
|
||||
{
|
||||
$this->current = array_merge($this->current, $currents);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $name
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $index
|
||||
*/
|
||||
public function setIndex($index)
|
||||
{
|
||||
$this->index = $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIndex()
|
||||
{
|
||||
return $this->index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $filename
|
||||
*/
|
||||
public function setFilename($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDependencies()
|
||||
{
|
||||
return $this->params['depends'];
|
||||
}
|
||||
|
||||
public function isBlocked()
|
||||
{
|
||||
return $this->getSkip() !== null || $this->getIncomplete() !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getFeature()
|
||||
{
|
||||
return $this->feature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $feature
|
||||
*/
|
||||
public function setFeature($feature)
|
||||
{
|
||||
$this->feature = $feature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $service
|
||||
* @return array
|
||||
* @throws InjectionException
|
||||
*/
|
||||
public function getService($service)
|
||||
{
|
||||
if (!isset($this->services[$service])) {
|
||||
throw new InjectionException("Service $service is not defined and can't be accessed from a test");
|
||||
}
|
||||
return $this->services[$service];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $services
|
||||
*/
|
||||
public function setServices($services)
|
||||
{
|
||||
$this->services = $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all test reports
|
||||
* @return array
|
||||
*/
|
||||
public function getReports()
|
||||
{
|
||||
return $this->reports;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $report
|
||||
*/
|
||||
public function addReport($type, $report)
|
||||
{
|
||||
$this->reports[$type] = $report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns test params like: env, group, skip, incomplete, etc
|
||||
* Can return by annotation or return all if no key passed
|
||||
*
|
||||
* @param null $key
|
||||
* @return array|mixed|null
|
||||
*/
|
||||
public function getParam($key = null)
|
||||
{
|
||||
if ($key) {
|
||||
if (isset($this->params[$key])) {
|
||||
return $this->params[$key];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $annotations
|
||||
*/
|
||||
public function setParamsFromAnnotations($annotations)
|
||||
{
|
||||
$params = Annotation::fetchAllAnnotationsFromDocblock($annotations);
|
||||
$this->params = array_merge_recursive($this->params, $params);
|
||||
|
||||
// set singular value for some params
|
||||
foreach (['skip', 'incomplete'] as $single) {
|
||||
$this->params[$single] = empty($this->params[$single]) ? null : (string) $this->params[$single][0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $params
|
||||
*/
|
||||
public function setParams($params)
|
||||
{
|
||||
$this->params = array_merge_recursive($this->params, $params);
|
||||
}
|
||||
}
|
||||
138
vendor/codeception/base/src/Codeception/Test/Test.php
vendored
Normal file
138
vendor/codeception/base/src/Codeception/Test/Test.php
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
namespace Codeception\Test;
|
||||
|
||||
use Codeception\TestInterface;
|
||||
use Codeception\Util\ReflectionHelper;
|
||||
use SebastianBergmann\Timer\Timer;
|
||||
|
||||
/**
|
||||
* The most simple testcase (with only one test in it) which can be executed by PHPUnit/Codeception.
|
||||
* It can be extended with included traits. Turning on/off a trait should not break class functionality.
|
||||
*
|
||||
* Class has exactly one method to be executed for testing, wrapped with before/after callbacks delivered from included traits.
|
||||
* A trait providing before/after callback should contain corresponding protected methods: `{traitName}Start` and `{traitName}End`,
|
||||
* then this trait should be enabled in `hooks` property.
|
||||
*
|
||||
* Inherited class must implement `test` method.
|
||||
*/
|
||||
abstract class Test implements TestInterface, Interfaces\Descriptive
|
||||
{
|
||||
use Feature\AssertionCounter;
|
||||
use Feature\CodeCoverage;
|
||||
use Feature\ErrorLogger;
|
||||
use Feature\MetadataCollector;
|
||||
use Feature\IgnoreIfMetadataBlocked;
|
||||
|
||||
private $testResult;
|
||||
private $ignored = false;
|
||||
|
||||
/**
|
||||
* Enabled traits with methods to be called before and after the test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hooks = [
|
||||
'ignoreIfMetadataBlocked',
|
||||
'codeCoverage',
|
||||
'assertionCounter',
|
||||
'errorLogger'
|
||||
];
|
||||
|
||||
const STATUS_FAIL = 'fail';
|
||||
const STATUS_ERROR = 'error';
|
||||
const STATUS_OK = 'ok';
|
||||
const STATUS_PENDING = 'pending';
|
||||
|
||||
/**
|
||||
* Everything inside this method is treated as a test.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function test();
|
||||
|
||||
/**
|
||||
* Test representation
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function toString();
|
||||
|
||||
/**
|
||||
* Runs a test and collects its result in a TestResult instance.
|
||||
* Executes before/after hooks coming from traits.
|
||||
*
|
||||
* @param \PHPUnit\Framework\TestResult $result
|
||||
* @return \PHPUnit\Framework\TestResult
|
||||
*/
|
||||
final public function run(\PHPUnit\Framework\TestResult $result = null)
|
||||
{
|
||||
$this->testResult = $result;
|
||||
|
||||
$status = self::STATUS_PENDING;
|
||||
$time = 0;
|
||||
$e = null;
|
||||
|
||||
$result->startTest($this);
|
||||
|
||||
foreach ($this->hooks as $hook) {
|
||||
if (method_exists($this, $hook.'Start')) {
|
||||
$this->{$hook.'Start'}();
|
||||
}
|
||||
}
|
||||
|
||||
$failedToStart = ReflectionHelper::readPrivateProperty($result, 'lastTestFailed');
|
||||
|
||||
if (!$this->ignored && !$failedToStart) {
|
||||
|
||||
Timer::start();
|
||||
try {
|
||||
$this->test();
|
||||
$status = self::STATUS_OK;
|
||||
} catch (\PHPUnit\Framework\AssertionFailedError $e) {
|
||||
$status = self::STATUS_FAIL;
|
||||
} catch (\PHPUnit\Framework\Exception $e) {
|
||||
$status = self::STATUS_ERROR;
|
||||
} catch (\Throwable $e) {
|
||||
$e = new \PHPUnit\Framework\ExceptionWrapper($e);
|
||||
$status = self::STATUS_ERROR;
|
||||
} catch (\Exception $e) {
|
||||
$e = new \PHPUnit\Framework\ExceptionWrapper($e);
|
||||
$status = self::STATUS_ERROR;
|
||||
}
|
||||
$time = Timer::stop();
|
||||
}
|
||||
|
||||
foreach (array_reverse($this->hooks) as $hook) {
|
||||
if (method_exists($this, $hook.'End')) {
|
||||
$this->{$hook.'End'}($status, $time, $e);
|
||||
}
|
||||
}
|
||||
|
||||
$result->endTest($this, $time);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getTestResultObject()
|
||||
{
|
||||
return $this->testResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class represents exactly one test
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should a test be skipped (can be set from hooks)
|
||||
*
|
||||
* @param boolean $ignored
|
||||
*/
|
||||
protected function ignore($ignored)
|
||||
{
|
||||
$this->ignored = $ignored;
|
||||
}
|
||||
}
|
||||
172
vendor/codeception/base/src/Codeception/Test/Unit.php
vendored
Normal file
172
vendor/codeception/base/src/Codeception/Test/Unit.php
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
namespace Codeception\Test;
|
||||
|
||||
use Codeception\Configuration;
|
||||
use Codeception\Exception\ModuleException;
|
||||
use Codeception\Lib\Di;
|
||||
use Codeception\Lib\Notification;
|
||||
use Codeception\Scenario;
|
||||
use Codeception\TestInterface;
|
||||
|
||||
/**
|
||||
* Represents tests from PHPUnit compatible format.
|
||||
*/
|
||||
class Unit extends \PHPUnit\Framework\TestCase implements
|
||||
Interfaces\Reported,
|
||||
Interfaces\Dependent,
|
||||
TestInterface
|
||||
{
|
||||
use \Codeception\Test\Feature\Stub;
|
||||
|
||||
/**
|
||||
* @var Metadata
|
||||
*/
|
||||
private $metadata;
|
||||
|
||||
public function getMetadata()
|
||||
{
|
||||
if (!$this->metadata) {
|
||||
$this->metadata = new Metadata();
|
||||
}
|
||||
return $this->metadata;
|
||||
}
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
if ($this->getMetadata()->isBlocked()) {
|
||||
if ($this->getMetadata()->getSkip() !== null) {
|
||||
$this->markTestSkipped($this->getMetadata()->getSkip());
|
||||
}
|
||||
if ($this->getMetadata()->getIncomplete() !== null) {
|
||||
$this->markTestIncomplete($this->getMetadata()->getIncomplete());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var $di Di **/
|
||||
$di = $this->getMetadata()->getService('di');
|
||||
$di->set(new Scenario($this));
|
||||
|
||||
// auto-inject $tester property
|
||||
if (($this->getMetadata()->getCurrent('actor')) && ($property = lcfirst(Configuration::config()['actor_suffix']))) {
|
||||
$this->$property = $di->instantiate($this->getMetadata()->getCurrent('actor'));
|
||||
}
|
||||
|
||||
// Auto inject into the _inject method
|
||||
$di->injectDependencies($this); // injecting dependencies
|
||||
$this->_before();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Override
|
||||
*/
|
||||
protected function _before()
|
||||
{
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
$this->_after();
|
||||
}
|
||||
|
||||
/**
|
||||
* @Override
|
||||
*/
|
||||
protected function _after()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* If the method exists (PHPUnit 5) forward the call to the parent class, otherwise
|
||||
* call `expectException` instead (PHPUnit 6)
|
||||
*/
|
||||
public function setExpectedException($exception, $message = null, $code = null)
|
||||
{
|
||||
if (is_callable('parent::setExpectedException')) {
|
||||
parent::setExpectedException($exception, $message, $code);
|
||||
} else {
|
||||
Notification::deprecate('PHPUnit\Framework\TestCase::setExpectedException deprecated in favor of expectException, expectExceptionMessage, and expectExceptionCode');
|
||||
$this->expectException($exception);
|
||||
if ($message !== null) {
|
||||
$this->expectExceptionMessage($message);
|
||||
}
|
||||
if ($code !== null) {
|
||||
$this->expectExceptionCode($code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $module
|
||||
* @return \Codeception\Module
|
||||
* @throws ModuleException
|
||||
*/
|
||||
public function getModule($module)
|
||||
{
|
||||
$modules = $this->getMetadata()->getCurrent('modules');
|
||||
if (!isset($modules[$module])) {
|
||||
throw new ModuleException($module, "Module can't be accessed");
|
||||
}
|
||||
return $modules[$module];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current values
|
||||
*/
|
||||
public function getCurrent($current)
|
||||
{
|
||||
return $this->getMetadata()->getCurrent($current);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getReportFields()
|
||||
{
|
||||
return [
|
||||
'name' => $this->getName(),
|
||||
'class' => get_class($this),
|
||||
'file' => $this->getMetadata()->getFilename()
|
||||
];
|
||||
}
|
||||
|
||||
public function fetchDependencies()
|
||||
{
|
||||
$names = [];
|
||||
foreach ($this->getMetadata()->getDependencies() as $required) {
|
||||
if ((strpos($required, ':') === false) and method_exists($this, $required)) {
|
||||
$required = get_class($this) . ":$required";
|
||||
}
|
||||
$names[] = $required;
|
||||
}
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset PHPUnit's dependencies
|
||||
* @return bool
|
||||
*/
|
||||
public function handleDependencies()
|
||||
{
|
||||
$dependencies = $this->fetchDependencies();
|
||||
if (empty($dependencies)) {
|
||||
return true;
|
||||
}
|
||||
$passed = $this->getTestResultObject()->passed();
|
||||
$dependencyInput = [];
|
||||
|
||||
foreach ($dependencies as $dependency) {
|
||||
$dependency = str_replace(':', '::', $dependency); // Codeception => PHPUnit format
|
||||
if (strpos($dependency, '::') === false) { // check it is method of same class
|
||||
$dependency = get_class($this) . '::' . $dependency;
|
||||
}
|
||||
if (isset($passed[$dependency])) {
|
||||
$dependencyInput[] = $passed[$dependency]['result'];
|
||||
} else {
|
||||
$dependencyInput[] = null;
|
||||
}
|
||||
}
|
||||
$this->setDependencyInput($dependencyInput);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user