init
This commit is contained in:
66
vendor/codeception/base/src/Codeception/Subscriber/AutoRebuild.php
vendored
Normal file
66
vendor/codeception/base/src/Codeception/Subscriber/AutoRebuild.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
namespace Codeception\Subscriber;
|
||||
|
||||
use Codeception\Configuration;
|
||||
use Codeception\Event\SuiteEvent;
|
||||
use Codeception\Events;
|
||||
use Codeception\Lib\Generator\Actions;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class AutoRebuild implements EventSubscriberInterface
|
||||
{
|
||||
use Shared\StaticEvents;
|
||||
|
||||
public static $events = [
|
||||
Events::SUITE_INIT => 'updateActor'
|
||||
];
|
||||
|
||||
public function updateActor(SuiteEvent $e)
|
||||
{
|
||||
$settings = $e->getSettings();
|
||||
if (!$settings['actor']) {
|
||||
codecept_debug('actor is empty');
|
||||
return; // no actor
|
||||
}
|
||||
|
||||
$modules = $e->getSuite()->getModules();
|
||||
|
||||
$actorActionsFile = Configuration::supportDir() . '_generated' . DIRECTORY_SEPARATOR
|
||||
. $settings['actor'] . 'Actions.php';
|
||||
|
||||
if (!file_exists($actorActionsFile)) {
|
||||
codecept_debug("Generating {$settings['actor']}Actions...");
|
||||
$this->generateActorActions($actorActionsFile, $settings);
|
||||
return;
|
||||
}
|
||||
|
||||
// load actor class to see hash
|
||||
$handle = @fopen($actorActionsFile, "r");
|
||||
if ($handle and is_writable($actorActionsFile)) {
|
||||
$line = @fgets($handle);
|
||||
if (preg_match('~\[STAMP\] ([a-f0-9]*)~', $line, $matches)) {
|
||||
$hash = $matches[1];
|
||||
$currentHash = Actions::genHash($modules, $settings);
|
||||
|
||||
// regenerate actor class when hashes do not match
|
||||
if ($hash != $currentHash) {
|
||||
codecept_debug("Rebuilding {$settings['actor']}...");
|
||||
@fclose($handle);
|
||||
$this->generateActorActions($actorActionsFile, $settings);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@fclose($handle);
|
||||
}
|
||||
}
|
||||
|
||||
protected function generateActorActions($actorActionsFile, $settings)
|
||||
{
|
||||
if (!file_exists(Configuration::supportDir() . '_generated')) {
|
||||
@mkdir(Configuration::supportDir() . '_generated');
|
||||
}
|
||||
$actionsGenerator = new Actions($settings);
|
||||
$generated = $actionsGenerator->produce();
|
||||
@file_put_contents($actorActionsFile, $generated);
|
||||
}
|
||||
}
|
||||
52
vendor/codeception/base/src/Codeception/Subscriber/BeforeAfterTest.php
vendored
Normal file
52
vendor/codeception/base/src/Codeception/Subscriber/BeforeAfterTest.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
namespace Codeception\Subscriber;
|
||||
|
||||
use Codeception\Event\SuiteEvent;
|
||||
use Codeception\Events;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class BeforeAfterTest implements EventSubscriberInterface
|
||||
{
|
||||
use Shared\StaticEvents;
|
||||
|
||||
public static $events = [
|
||||
Events::SUITE_BEFORE => 'beforeClass',
|
||||
Events::SUITE_AFTER => ['afterClass', 100]
|
||||
];
|
||||
|
||||
protected $hooks = [];
|
||||
protected $startedTests = [];
|
||||
protected $unsuccessfulTests = [];
|
||||
|
||||
public function beforeClass(SuiteEvent $e)
|
||||
{
|
||||
foreach ($e->getSuite()->tests() as $test) {
|
||||
/** @var $test \PHPUnit\Framework\Test * */
|
||||
if ($test instanceof \PHPUnit\Framework\TestSuite\DataProvider) {
|
||||
$potentialTestClass = strstr($test->getName(), '::', true);
|
||||
$this->hooks[$potentialTestClass] = \PHPUnit\Util\Test::getHookMethods($potentialTestClass);
|
||||
}
|
||||
|
||||
$testClass = get_class($test);
|
||||
$this->hooks[$testClass] = \PHPUnit\Util\Test::getHookMethods($testClass);
|
||||
}
|
||||
$this->runHooks('beforeClass');
|
||||
}
|
||||
|
||||
|
||||
public function afterClass(SuiteEvent $e)
|
||||
{
|
||||
$this->runHooks('afterClass');
|
||||
}
|
||||
|
||||
protected function runHooks($hookName)
|
||||
{
|
||||
foreach ($this->hooks as $className => $hook) {
|
||||
foreach ($hook[$hookName] as $method) {
|
||||
if (is_callable([$className, $method])) {
|
||||
call_user_func([$className, $method]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
vendor/codeception/base/src/Codeception/Subscriber/Bootstrap.php
vendored
Normal file
36
vendor/codeception/base/src/Codeception/Subscriber/Bootstrap.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace Codeception\Subscriber;
|
||||
|
||||
use Codeception\Event\SuiteEvent;
|
||||
use Codeception\Events;
|
||||
use Codeception\Exception\ConfigurationException;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class Bootstrap implements EventSubscriberInterface
|
||||
{
|
||||
use Shared\StaticEvents;
|
||||
|
||||
public static $events = [
|
||||
Events::SUITE_INIT => 'loadBootstrap',
|
||||
];
|
||||
|
||||
public function loadBootstrap(SuiteEvent $e)
|
||||
{
|
||||
$settings = $e->getSettings();
|
||||
|
||||
if (!isset($settings['bootstrap'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$settings['bootstrap']) {
|
||||
return;
|
||||
}
|
||||
|
||||
$bootstrap = $settings['path'] . $settings['bootstrap'];
|
||||
if (!is_file($bootstrap)) {
|
||||
throw new ConfigurationException("Bootstrap file $bootstrap can't be loaded");
|
||||
}
|
||||
|
||||
require_once $bootstrap;
|
||||
}
|
||||
}
|
||||
646
vendor/codeception/base/src/Codeception/Subscriber/Console.php
vendored
Normal file
646
vendor/codeception/base/src/Codeception/Subscriber/Console.php
vendored
Normal file
@@ -0,0 +1,646 @@
|
||||
<?php
|
||||
namespace Codeception\Subscriber;
|
||||
|
||||
use Codeception\Event\FailEvent;
|
||||
use Codeception\Event\PrintResultEvent;
|
||||
use Codeception\Event\StepEvent;
|
||||
use Codeception\Event\SuiteEvent;
|
||||
use Codeception\Event\TestEvent;
|
||||
use Codeception\Events;
|
||||
use Codeception\Lib\Console\Message;
|
||||
use Codeception\Lib\Console\MessageFactory;
|
||||
use Codeception\Lib\Console\Output;
|
||||
use Codeception\Lib\Notification;
|
||||
use Codeception\Step;
|
||||
use Codeception\Step\Comment;
|
||||
use Codeception\Suite;
|
||||
use Codeception\Test\Descriptor;
|
||||
use Codeception\Test\Interfaces\ScenarioDriven;
|
||||
use Codeception\Util\Debug;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatter;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class Console implements EventSubscriberInterface
|
||||
{
|
||||
use Shared\StaticEvents;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public static $events = [
|
||||
Events::SUITE_BEFORE => 'beforeSuite',
|
||||
Events::SUITE_AFTER => 'afterSuite',
|
||||
Events::TEST_START => 'startTest',
|
||||
Events::TEST_END => 'endTest',
|
||||
Events::STEP_BEFORE => 'beforeStep',
|
||||
Events::STEP_AFTER => 'afterStep',
|
||||
Events::TEST_SUCCESS => 'testSuccess',
|
||||
Events::TEST_FAIL => 'testFail',
|
||||
Events::TEST_ERROR => 'testError',
|
||||
Events::TEST_INCOMPLETE => 'testIncomplete',
|
||||
Events::TEST_SKIPPED => 'testSkipped',
|
||||
Events::TEST_WARNING => 'testWarning',
|
||||
Events::TEST_FAIL_PRINT => 'printFail',
|
||||
Events::RESULT_PRINT_AFTER => 'afterResult',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var Step
|
||||
*/
|
||||
protected $metaStep;
|
||||
|
||||
/**
|
||||
* @var Message
|
||||
*/
|
||||
protected $message = null;
|
||||
protected $steps = true;
|
||||
protected $debug = false;
|
||||
protected $ansi = true;
|
||||
protected $silent = false;
|
||||
protected $lastTestFailed = false;
|
||||
protected $printedTest = null;
|
||||
protected $rawStackTrace = false;
|
||||
protected $traceLength = 5;
|
||||
protected $width;
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
protected $output;
|
||||
protected $conditionalFails = [];
|
||||
protected $failedStep = [];
|
||||
protected $reports = [];
|
||||
protected $namespace = '';
|
||||
protected $chars = ['success' => '+', 'fail' => 'x', 'of' => ':'];
|
||||
|
||||
protected $options = [
|
||||
'debug' => false,
|
||||
'ansi' => false,
|
||||
'steps' => true,
|
||||
'verbosity' => 0,
|
||||
'xml' => null,
|
||||
'html' => null,
|
||||
'tap' => null,
|
||||
'json' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var MessageFactory
|
||||
*/
|
||||
protected $messageFactory;
|
||||
|
||||
public function __construct($options)
|
||||
{
|
||||
$this->prepareOptions($options);
|
||||
$this->output = new Output($options);
|
||||
$this->messageFactory = new MessageFactory($this->output);
|
||||
if ($this->debug) {
|
||||
Debug::setOutput($this->output);
|
||||
}
|
||||
$this->detectWidth();
|
||||
|
||||
if ($this->options['ansi'] && !$this->isWin()) {
|
||||
$this->chars['success'] = '✔';
|
||||
$this->chars['fail'] = '✖';
|
||||
}
|
||||
|
||||
foreach (['html', 'xml', 'tap', 'json'] as $report) {
|
||||
if (!$this->options[$report]) {
|
||||
continue;
|
||||
}
|
||||
$path = $this->absolutePath($this->options[$report]);
|
||||
$this->reports[] = sprintf(
|
||||
"- <bold>%s</bold> report generated in <comment>file://%s</comment>",
|
||||
strtoupper($report),
|
||||
$path
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// triggered for scenario based tests: cept, cest
|
||||
public function beforeSuite(SuiteEvent $e)
|
||||
{
|
||||
$this->namespace = "";
|
||||
$settings = $e->getSettings();
|
||||
if (isset($settings['namespace'])) {
|
||||
$this->namespace = $settings['namespace'];
|
||||
}
|
||||
$this->message("%s Tests (%d) ")
|
||||
->with(ucfirst($e->getSuite()->getName()), $e->getSuite()->count())
|
||||
->style('bold')
|
||||
->width($this->width, '-')
|
||||
->prepend("\n")
|
||||
->writeln();
|
||||
|
||||
if ($e->getSuite() instanceof Suite) {
|
||||
$message = $this->message(
|
||||
implode(
|
||||
', ',
|
||||
array_map(
|
||||
function ($module) {
|
||||
return $module->_getName();
|
||||
},
|
||||
$e->getSuite()->getModules()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$message->style('info')
|
||||
->prepend('Modules: ')
|
||||
->writeln(OutputInterface::VERBOSITY_VERBOSE);
|
||||
}
|
||||
|
||||
$this->message('')->width($this->width, '-')->writeln(OutputInterface::VERBOSITY_VERBOSE);
|
||||
}
|
||||
|
||||
// triggered for all tests
|
||||
public function startTest(TestEvent $e)
|
||||
{
|
||||
$this->conditionalFails = [];
|
||||
$test = $e->getTest();
|
||||
$this->printedTest = $test;
|
||||
$this->message = null;
|
||||
|
||||
if (!$this->output->isInteractive() and !$this->isDetailed($test)) {
|
||||
return;
|
||||
}
|
||||
$this->writeCurrentTest($test);
|
||||
if ($this->isDetailed($test)) {
|
||||
$this->output->writeln('');
|
||||
$this->message(Descriptor::getTestSignature($test))
|
||||
->style('info')
|
||||
->prepend('Signature: ')
|
||||
->writeln();
|
||||
|
||||
$this->message(codecept_relative_path(Descriptor::getTestFullName($test)))
|
||||
->style('info')
|
||||
->prepend('Test: ')
|
||||
->writeln();
|
||||
|
||||
if ($this->steps) {
|
||||
$this->message('Scenario --')->style('comment')->writeln();
|
||||
$this->output->waitForDebugOutput = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function afterStep(StepEvent $e)
|
||||
{
|
||||
$step = $e->getStep();
|
||||
if (!$step->hasFailed()) {
|
||||
return;
|
||||
}
|
||||
if ($step instanceof Step\ConditionalAssertion) {
|
||||
$this->conditionalFails[] = $step;
|
||||
return;
|
||||
}
|
||||
$this->failedStep[] = $step;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PrintResultEvent $event
|
||||
*/
|
||||
public function afterResult(PrintResultEvent $event)
|
||||
{
|
||||
$result = $event->getResult();
|
||||
if ($result->skippedCount() + $result->notImplementedCount() > 0 and $this->options['verbosity'] < OutputInterface::VERBOSITY_VERBOSE) {
|
||||
$this->output->writeln("run with `-v` to get more info about skipped or incomplete tests");
|
||||
}
|
||||
foreach ($this->reports as $message) {
|
||||
$this->output->writeln($message);
|
||||
}
|
||||
}
|
||||
|
||||
private function absolutePath($path)
|
||||
{
|
||||
if ((strpos($path, '/') === 0) or (strpos($path, ':') === 1)) { // absolute path
|
||||
return $path;
|
||||
}
|
||||
|
||||
return codecept_output_dir() . $path;
|
||||
}
|
||||
|
||||
public function testSuccess(TestEvent $e)
|
||||
{
|
||||
if ($this->isDetailed($e->getTest())) {
|
||||
$this->message('PASSED')->center(' ')->style('ok')->append("\n")->writeln();
|
||||
|
||||
return;
|
||||
}
|
||||
$this->writelnFinishedTest($e, $this->message($this->chars['success'])->style('ok'));
|
||||
}
|
||||
|
||||
public function endTest(TestEvent $e)
|
||||
{
|
||||
$this->metaStep = null;
|
||||
$this->printedTest = null;
|
||||
}
|
||||
|
||||
public function testWarning(TestEvent $e)
|
||||
{
|
||||
if ($this->isDetailed($e->getTest())) {
|
||||
$this->message('WARNING')->center(' ')->style('pending')->append("\n")->writeln();
|
||||
|
||||
return;
|
||||
}
|
||||
$this->writelnFinishedTest($e, $this->message('W')->style('pending'));
|
||||
}
|
||||
|
||||
public function testFail(FailEvent $e)
|
||||
{
|
||||
if ($this->isDetailed($e->getTest())) {
|
||||
$this->message('FAIL')->center(' ')->style('fail')->append("\n")->writeln();
|
||||
|
||||
return;
|
||||
}
|
||||
$this->writelnFinishedTest($e, $this->message($this->chars['fail'])->style('fail'));
|
||||
}
|
||||
|
||||
public function testError(FailEvent $e)
|
||||
{
|
||||
if ($this->isDetailed($e->getTest())) {
|
||||
$this->message('ERROR')->center(' ')->style('fail')->append("\n")->writeln();
|
||||
|
||||
return;
|
||||
}
|
||||
$this->writelnFinishedTest($e, $this->message('E')->style('fail'));
|
||||
}
|
||||
|
||||
public function testSkipped(FailEvent $e)
|
||||
{
|
||||
if ($this->isDetailed($e->getTest())) {
|
||||
$msg = $e->getFail()->getMessage();
|
||||
$this->message('SKIPPED')->append($msg ? ": $msg" : '')->center(' ')->style('pending')->writeln();
|
||||
|
||||
return;
|
||||
}
|
||||
$this->writelnFinishedTest($e, $this->message('S')->style('pending'));
|
||||
}
|
||||
|
||||
public function testIncomplete(FailEvent $e)
|
||||
{
|
||||
if ($this->isDetailed($e->getTest())) {
|
||||
$msg = $e->getFail()->getMessage();
|
||||
$this->message('INCOMPLETE')->append($msg ? ": $msg" : '')->center(' ')->style('pending')->writeln();
|
||||
|
||||
return;
|
||||
}
|
||||
$this->writelnFinishedTest($e, $this->message('I')->style('pending'));
|
||||
}
|
||||
|
||||
protected function isDetailed($test)
|
||||
{
|
||||
if ($test instanceof ScenarioDriven && $this->steps) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function beforeStep(StepEvent $e)
|
||||
{
|
||||
if (!$this->steps or !$e->getTest() instanceof ScenarioDriven) {
|
||||
return;
|
||||
}
|
||||
$metaStep = $e->getStep()->getMetaStep();
|
||||
if ($metaStep and $this->metaStep != $metaStep) {
|
||||
$this->message(' ' . $metaStep->getPrefix())
|
||||
->style('bold')
|
||||
->append($metaStep->__toString())
|
||||
->writeln();
|
||||
}
|
||||
$this->metaStep = $metaStep;
|
||||
|
||||
$this->printStep($e->getStep());
|
||||
}
|
||||
|
||||
private function printStep(Step $step)
|
||||
{
|
||||
if ($step instanceof Comment and $step->__toString() == '') {
|
||||
return; // don't print empty comments
|
||||
}
|
||||
$msg = $this->message(' ');
|
||||
if ($this->metaStep) {
|
||||
$msg->append(' ');
|
||||
}
|
||||
$msg->append($step->getPrefix());
|
||||
$prefixLength = $msg->getLength();
|
||||
if (!$this->metaStep) {
|
||||
$msg->style('bold');
|
||||
}
|
||||
$maxLength = $this->width - $prefixLength;
|
||||
$msg->append(OutputFormatter::escape($step->toString($maxLength)));
|
||||
if ($this->metaStep) {
|
||||
$msg->style('info');
|
||||
}
|
||||
$msg->writeln();
|
||||
}
|
||||
|
||||
public function afterSuite(SuiteEvent $e)
|
||||
{
|
||||
$this->message()->width($this->width, '-')->writeln();
|
||||
$messages = Notification::all();
|
||||
foreach (array_count_values($messages) as $message => $count) {
|
||||
if ($count > 1) {
|
||||
$message = $count . 'x ' . $message;
|
||||
}
|
||||
$this->output->notification($message);
|
||||
}
|
||||
}
|
||||
|
||||
public function printFail(FailEvent $e)
|
||||
{
|
||||
$failedTest = $e->getTest();
|
||||
$fail = $e->getFail();
|
||||
|
||||
$this->output->write($e->getCount() . ") ");
|
||||
$this->writeCurrentTest($failedTest, false);
|
||||
$this->output->writeln('');
|
||||
$this->message("<error> Test </error> ")
|
||||
->append(codecept_relative_path(Descriptor::getTestFullName($failedTest)))
|
||||
->write();
|
||||
|
||||
if ($failedTest instanceof ScenarioDriven) {
|
||||
$this->printScenarioFail($failedTest, $fail);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->printException($fail);
|
||||
$this->printExceptionTrace($fail);
|
||||
}
|
||||
|
||||
public function printException($e, $cause = null)
|
||||
{
|
||||
if ($e instanceof \PHPUnit\Framework\SkippedTestError or $e instanceof \PHPUnit\Framework_IncompleteTestError) {
|
||||
if ($e->getMessage()) {
|
||||
$this->message(OutputFormatter::escape($e->getMessage()))->prepend("\n")->writeln();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$class = $e instanceof \PHPUnit\Framework\ExceptionWrapper
|
||||
? $e->getClassname()
|
||||
: get_class($e);
|
||||
|
||||
if (strpos($class, 'Codeception\Exception') === 0) {
|
||||
$class = substr($class, strlen('Codeception\Exception\\'));
|
||||
}
|
||||
|
||||
$this->output->writeln('');
|
||||
$message = $this->message(OutputFormatter::escape($e->getMessage()));
|
||||
|
||||
if ($e instanceof \PHPUnit\Framework\ExpectationFailedException) {
|
||||
$comparisonFailure = $e->getComparisonFailure();
|
||||
if ($comparisonFailure) {
|
||||
$message->append($this->messageFactory->prepareComparisonFailureMessage($comparisonFailure));
|
||||
}
|
||||
}
|
||||
|
||||
$isFailure = $e instanceof \PHPUnit\Framework\AssertionFailedError
|
||||
|| $class === 'PHPUnit\Framework\ExpectationFailedException'
|
||||
|| $class === 'PHPUnit\Framework\AssertionFailedError';
|
||||
|
||||
if (!$isFailure) {
|
||||
$message->prepend("[$class] ")->block('error');
|
||||
}
|
||||
|
||||
if ($isFailure && $cause) {
|
||||
$cause = OutputFormatter::escape(ucfirst($cause));
|
||||
$message->prepend("<error> Step </error> $cause\n<error> Fail </error> ");
|
||||
}
|
||||
|
||||
$message->writeln();
|
||||
}
|
||||
|
||||
public function printScenarioFail(ScenarioDriven $failedTest, $fail)
|
||||
{
|
||||
if ($this->conditionalFails) {
|
||||
$failedStep = (string) array_shift($this->conditionalFails);
|
||||
} else {
|
||||
$failedStep = (string) $failedTest->getScenario()->getMetaStep();
|
||||
if ($failedStep === '') {
|
||||
$failedStep = (string) array_shift($this->failedStep);
|
||||
}
|
||||
}
|
||||
|
||||
$this->printException($fail, $failedStep);
|
||||
|
||||
$this->printScenarioTrace($failedTest);
|
||||
if ($this->output->getVerbosity() == OutputInterface::VERBOSITY_DEBUG) {
|
||||
$this->printExceptionTrace($fail);
|
||||
|
||||
return;
|
||||
}
|
||||
if (!$fail instanceof \PHPUnit\Framework\AssertionFailedError) {
|
||||
$this->printExceptionTrace($fail);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public function printExceptionTrace($e)
|
||||
{
|
||||
static $limit = 10;
|
||||
|
||||
if ($e instanceof \PHPUnit\Framework\SkippedTestError or $e instanceof \PHPUnit\Framework_IncompleteTestError) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->rawStackTrace) {
|
||||
$this->message(OutputFormatter::escape(\PHPUnit\Util\Filter::getFilteredStacktrace($e, true, false)))->writeln();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$trace = \PHPUnit\Util\Filter::getFilteredStacktrace($e, false);
|
||||
|
||||
$i = 0;
|
||||
foreach ($trace as $step) {
|
||||
if ($i >= $limit) {
|
||||
break;
|
||||
}
|
||||
$i++;
|
||||
|
||||
$message = $this->message($i)->prepend('#')->width(4);
|
||||
|
||||
if (!isset($step['file'])) {
|
||||
foreach (['class', 'type', 'function'] as $info) {
|
||||
if (!isset($step[$info])) {
|
||||
continue;
|
||||
}
|
||||
$message->append($step[$info]);
|
||||
}
|
||||
$message->writeln();
|
||||
continue;
|
||||
}
|
||||
$message->append($step['file'] . ':' . $step['line']);
|
||||
$message->writeln();
|
||||
}
|
||||
|
||||
$prev = $e->getPrevious();
|
||||
if ($prev) {
|
||||
$this->printExceptionTrace($prev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $failedTest
|
||||
*/
|
||||
public function printScenarioTrace(ScenarioDriven $failedTest)
|
||||
{
|
||||
$trace = array_reverse($failedTest->getScenario()->getSteps());
|
||||
$length = $stepNumber = count($trace);
|
||||
|
||||
if (!$length) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->message("\nScenario Steps:\n")->style('comment')->writeln();
|
||||
|
||||
foreach ($trace as $step) {
|
||||
/**
|
||||
* @var $step Step
|
||||
*/
|
||||
if (!$step->__toString()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$message = $this
|
||||
->message($stepNumber)
|
||||
->prepend(' ')
|
||||
->width(strlen($length))
|
||||
->append(". ");
|
||||
$message->append(OutputFormatter::escape($step->getPhpCode($this->width - $message->getLength())));
|
||||
|
||||
if ($step->hasFailed()) {
|
||||
$message->style('bold');
|
||||
}
|
||||
|
||||
$line = $step->getLine();
|
||||
if ($line and (!$step instanceof Comment)) {
|
||||
$message->append(" at <info>$line</info>");
|
||||
}
|
||||
|
||||
$stepNumber--;
|
||||
$message->writeln();
|
||||
if (($length - $stepNumber - 1) >= $this->traceLength) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->output->writeln("");
|
||||
}
|
||||
|
||||
public function detectWidth()
|
||||
{
|
||||
$this->width = 60;
|
||||
if (!$this->isWin()
|
||||
&& (php_sapi_name() === "cli")
|
||||
&& (getenv('TERM'))
|
||||
&& (getenv('TERM') != 'unknown')
|
||||
) {
|
||||
// try to get terminal width from ENV variable (bash), see also https://github.com/Codeception/Codeception/issues/3788
|
||||
if (getenv('COLUMNS')) {
|
||||
$this->width = getenv('COLUMNS');
|
||||
} else {
|
||||
$this->width = (int) (`command -v tput >> /dev/null 2>&1 && tput cols`) - 2;
|
||||
}
|
||||
} elseif ($this->isWin() && (php_sapi_name() === "cli")) {
|
||||
exec('mode con', $output);
|
||||
if (isset($output[4])) {
|
||||
preg_match('/^ +.* +(\d+)$/', $output[4], $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$this->width = (int) $matches[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
private function isWin()
|
||||
{
|
||||
return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \PHPUnit\Framework\SelfDescribing $test
|
||||
* @param bool $inProgress
|
||||
*/
|
||||
protected function writeCurrentTest(\PHPUnit\Framework\SelfDescribing $test, $inProgress = true)
|
||||
{
|
||||
$prefix = ($this->output->isInteractive() and !$this->isDetailed($test) and $inProgress) ? '- ' : '';
|
||||
|
||||
$testString = Descriptor::getTestAsString($test);
|
||||
$testString = preg_replace('~^([^:]+):\s~', "<focus>$1{$this->chars['of']}</focus> ", $testString);
|
||||
|
||||
$this
|
||||
->message($testString)
|
||||
->prepend($prefix)
|
||||
->write();
|
||||
}
|
||||
|
||||
protected function writelnFinishedTest(TestEvent $event, Message $result)
|
||||
{
|
||||
$test = $event->getTest();
|
||||
if ($this->isDetailed($test)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->output->isInteractive()) {
|
||||
$this->output->write("\x0D");
|
||||
}
|
||||
$result->append(' ')->write();
|
||||
$this->writeCurrentTest($test, false);
|
||||
|
||||
$conditionalFailsMessage = "";
|
||||
$numFails = count($this->conditionalFails);
|
||||
if ($numFails == 1) {
|
||||
$conditionalFailsMessage = "[F]";
|
||||
} elseif ($numFails) {
|
||||
$conditionalFailsMessage = "{$numFails}x[F]";
|
||||
}
|
||||
$conditionalFailsMessage = "<error>$conditionalFailsMessage</error> ";
|
||||
$this->message($conditionalFailsMessage)->write();
|
||||
$this->writeTimeInformation($event);
|
||||
$this->output->writeln('');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $string
|
||||
* @return Message
|
||||
*/
|
||||
private function message($string = '')
|
||||
{
|
||||
return $this->messageFactory->message($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TestEvent $event
|
||||
*/
|
||||
protected function writeTimeInformation(TestEvent $event)
|
||||
{
|
||||
$time = $event->getTime();
|
||||
if ($time) {
|
||||
$this
|
||||
->message(number_format(round($time, 2), 2))
|
||||
->prepend('(')
|
||||
->append('s)')
|
||||
->style('info')
|
||||
->write();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $options
|
||||
*/
|
||||
private function prepareOptions($options)
|
||||
{
|
||||
$this->options = array_merge($this->options, $options);
|
||||
$this->debug = $this->options['debug'] || $this->options['verbosity'] >= OutputInterface::VERBOSITY_VERY_VERBOSE;
|
||||
$this->steps = $this->debug || $this->options['steps'];
|
||||
$this->rawStackTrace = ($this->options['verbosity'] === OutputInterface::VERBOSITY_DEBUG);
|
||||
}
|
||||
}
|
||||
46
vendor/codeception/base/src/Codeception/Subscriber/Dependencies.php
vendored
Normal file
46
vendor/codeception/base/src/Codeception/Subscriber/Dependencies.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace Codeception\Subscriber;
|
||||
|
||||
use Codeception\Event\TestEvent;
|
||||
use Codeception\Test\Descriptor;
|
||||
use Codeception\Test\Interfaces\Dependent;
|
||||
use Codeception\TestInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Codeception\Events;
|
||||
|
||||
class Dependencies implements EventSubscriberInterface
|
||||
{
|
||||
use Shared\StaticEvents;
|
||||
|
||||
static $events = [
|
||||
Events::TEST_START => 'testStart',
|
||||
Events::TEST_SUCCESS => 'testSuccess'
|
||||
];
|
||||
|
||||
protected $successfulTests = [];
|
||||
|
||||
public function testStart(TestEvent $event)
|
||||
{
|
||||
$test = $event->getTest();
|
||||
if (!$test instanceof Dependent) {
|
||||
return;
|
||||
}
|
||||
|
||||
$testSignatures = $test->fetchDependencies();
|
||||
foreach ($testSignatures as $signature) {
|
||||
if (!in_array($signature, $this->successfulTests)) {
|
||||
$test->getMetadata()->setSkip("This test depends on $signature to pass");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testSuccess(TestEvent $event)
|
||||
{
|
||||
$test = $event->getTest();
|
||||
if (!$test instanceof TestInterface) {
|
||||
return;
|
||||
}
|
||||
$this->successfulTests[] = Descriptor::getTestSignature($test);
|
||||
}
|
||||
}
|
||||
151
vendor/codeception/base/src/Codeception/Subscriber/ErrorHandler.php
vendored
Normal file
151
vendor/codeception/base/src/Codeception/Subscriber/ErrorHandler.php
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
namespace Codeception\Subscriber;
|
||||
|
||||
use Codeception\Event\SuiteEvent;
|
||||
use Codeception\Events;
|
||||
use Codeception\Lib\Notification;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class ErrorHandler implements EventSubscriberInterface
|
||||
{
|
||||
use Shared\StaticEvents;
|
||||
|
||||
public static $events = [
|
||||
Events::SUITE_BEFORE => 'handle',
|
||||
Events::SUITE_AFTER => 'onFinish'
|
||||
];
|
||||
|
||||
/**
|
||||
* @var bool $stopped to keep shutdownHandler from possible looping.
|
||||
*/
|
||||
private $stopped = false;
|
||||
|
||||
/**
|
||||
* @var bool $initialized to avoid double error handler substitution
|
||||
*/
|
||||
private $initialized = false;
|
||||
|
||||
private $deprecationsInstalled = false;
|
||||
private $oldHandler;
|
||||
|
||||
private $suiteFinished = false;
|
||||
|
||||
/**
|
||||
* @var int stores bitmask for errors
|
||||
*/
|
||||
private $errorLevel;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->errorLevel = E_ALL & ~E_STRICT & ~E_DEPRECATED;
|
||||
}
|
||||
|
||||
public function onFinish(SuiteEvent $e)
|
||||
{
|
||||
$this->suiteFinished = true;
|
||||
}
|
||||
|
||||
public function handle(SuiteEvent $e)
|
||||
{
|
||||
$settings = $e->getSettings();
|
||||
if ($settings['error_level']) {
|
||||
$this->errorLevel = eval("return {$settings['error_level']};");
|
||||
}
|
||||
error_reporting($this->errorLevel);
|
||||
|
||||
if ($this->initialized) {
|
||||
return;
|
||||
}
|
||||
// We must register shutdown function before deprecation error handler to restore previous error handler
|
||||
// and silence DeprecationErrorHandler yelling about 'THE ERROR HANDLER HAS CHANGED!'
|
||||
register_shutdown_function([$this, 'shutdownHandler']);
|
||||
$this->registerDeprecationErrorHandler();
|
||||
$this->oldHandler = set_error_handler([$this, 'errorHandler']);
|
||||
$this->initialized = true;
|
||||
}
|
||||
|
||||
public function errorHandler($errno, $errstr, $errfile, $errline, $context = array())
|
||||
{
|
||||
if (E_USER_DEPRECATED === $errno) {
|
||||
$this->handleDeprecationError($errno, $errstr, $errfile, $errline, $context);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(error_reporting() & $errno)) {
|
||||
// This error code is not included in error_reporting
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strpos($errstr, 'Cannot modify header information') !== false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw new \PHPUnit\Framework\Exception($errstr, $errno);
|
||||
}
|
||||
|
||||
public function shutdownHandler()
|
||||
{
|
||||
if ($this->deprecationsInstalled) {
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
if ($this->stopped) {
|
||||
return;
|
||||
}
|
||||
$this->stopped = true;
|
||||
$error = error_get_last();
|
||||
|
||||
if (!$this->suiteFinished && (
|
||||
$error === null || !in_array($error['type'], [E_ERROR, E_COMPILE_ERROR, E_CORE_ERROR])
|
||||
)) {
|
||||
throw new \RuntimeException('Command Did Not Finish Properly');
|
||||
} elseif (!is_array($error)) {
|
||||
return;
|
||||
}
|
||||
if (error_reporting() === 0) {
|
||||
return;
|
||||
}
|
||||
// not fatal
|
||||
if ($error['type'] > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo "\n\n\nFATAL ERROR. TESTS NOT FINISHED.\n";
|
||||
echo sprintf("%s \nin %s:%d\n", $error['message'], $error['file'], $error['line']);
|
||||
}
|
||||
|
||||
private function registerDeprecationErrorHandler()
|
||||
{
|
||||
if (class_exists('\Symfony\Bridge\PhpUnit\DeprecationErrorHandler') && 'disabled' !== getenv('SYMFONY_DEPRECATIONS_HELPER')) {
|
||||
// DeprecationErrorHandler only will be installed if array('PHPUnit\Util\ErrorHandler', 'handleError')
|
||||
// is installed or no other error handlers are installed.
|
||||
// So we will remove Symfony\Component\Debug\ErrorHandler if it's installed.
|
||||
$old = set_error_handler('var_dump');
|
||||
restore_error_handler();
|
||||
|
||||
if ($old
|
||||
&& is_array($old)
|
||||
&& count($old) > 0
|
||||
&& is_object($old[0])
|
||||
&& get_class($old[0]) === 'Symfony\Component\Debug\ErrorHandler'
|
||||
) {
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
$this->deprecationsInstalled = true;
|
||||
\Symfony\Bridge\PhpUnit\DeprecationErrorHandler::register(getenv('SYMFONY_DEPRECATIONS_HELPER'));
|
||||
}
|
||||
}
|
||||
|
||||
private function handleDeprecationError($type, $message, $file, $line, $context)
|
||||
{
|
||||
if (!($this->errorLevel & $type)) {
|
||||
return;
|
||||
}
|
||||
if ($this->deprecationsInstalled && $this->oldHandler) {
|
||||
call_user_func($this->oldHandler, $type, $message, $file, $line, $context);
|
||||
return;
|
||||
}
|
||||
Notification::deprecate("$message", "$file:$line");
|
||||
}
|
||||
}
|
||||
128
vendor/codeception/base/src/Codeception/Subscriber/ExtensionLoader.php
vendored
Normal file
128
vendor/codeception/base/src/Codeception/Subscriber/ExtensionLoader.php
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
namespace Codeception\Subscriber;
|
||||
|
||||
use Codeception\Configuration;
|
||||
use Codeception\Event\SuiteEvent;
|
||||
use Codeception\Events;
|
||||
use Codeception\Exception\ConfigurationException;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class ExtensionLoader implements EventSubscriberInterface
|
||||
{
|
||||
use Shared\StaticEvents;
|
||||
|
||||
public static $events = [
|
||||
Events::MODULE_INIT => 'registerSuiteExtensions',
|
||||
Events::SUITE_AFTER => 'stopSuiteExtensions'
|
||||
];
|
||||
|
||||
protected $config;
|
||||
protected $options = [];
|
||||
|
||||
protected $globalExtensions = [];
|
||||
protected $suiteExtensions = [];
|
||||
|
||||
/**
|
||||
* @var EventDispatcher
|
||||
*/
|
||||
protected $dispatcher;
|
||||
|
||||
public function __construct(EventDispatcher $dispatcher)
|
||||
{
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->config = Configuration::config();
|
||||
}
|
||||
|
||||
public function bootGlobalExtensions($options)
|
||||
{
|
||||
$this->options = $options;
|
||||
$this->globalExtensions = $this->bootExtensions($this->config);
|
||||
}
|
||||
|
||||
public function registerGlobalExtensions()
|
||||
{
|
||||
foreach ($this->globalExtensions as $extension) {
|
||||
$this->dispatcher->addSubscriber($extension);
|
||||
}
|
||||
}
|
||||
|
||||
public function registerSuiteExtensions(SuiteEvent $e)
|
||||
{
|
||||
$suiteConfig = $e->getSettings();
|
||||
$extensions = $this->bootExtensions($suiteConfig);
|
||||
|
||||
$this->suiteExtensions = [];
|
||||
foreach ($extensions as $extension) {
|
||||
$extensionClass = get_class($extension);
|
||||
if (isset($this->globalExtensions[$extensionClass])) {
|
||||
continue; // already globally enabled
|
||||
}
|
||||
$this->dispatcher->addSubscriber($extension);
|
||||
$this->suiteExtensions[$extensionClass] = $extension;
|
||||
}
|
||||
}
|
||||
|
||||
public function stopSuiteExtensions()
|
||||
{
|
||||
foreach ($this->suiteExtensions as $extension) {
|
||||
$this->dispatcher->removeSubscriber($extension);
|
||||
}
|
||||
$this->suiteExtensions = [];
|
||||
}
|
||||
|
||||
protected function bootExtensions($config)
|
||||
{
|
||||
$extensions = [];
|
||||
|
||||
foreach ($config['extensions']['enabled'] as $extensionClass) {
|
||||
if (is_array($extensionClass)) {
|
||||
$extensionClass = key($extensionClass);
|
||||
}
|
||||
if (!class_exists($extensionClass)) {
|
||||
throw new ConfigurationException(
|
||||
"Class `$extensionClass` is not defined. Autoload it or include into "
|
||||
. "'_bootstrap.php' file of 'tests' directory"
|
||||
);
|
||||
}
|
||||
$extensionConfig = $this->getExtensionConfig($extensionClass, $config);
|
||||
|
||||
$extension = new $extensionClass($extensionConfig, $this->options);
|
||||
if (!$extension instanceof EventSubscriberInterface) {
|
||||
throw new ConfigurationException(
|
||||
"Class $extensionClass is not an EventListener. Please create it as Extension or GroupObject."
|
||||
);
|
||||
}
|
||||
$extensions[get_class($extension)] = $extension;
|
||||
}
|
||||
return $extensions;
|
||||
}
|
||||
|
||||
private function getExtensionConfig($extension, $config)
|
||||
{
|
||||
$extensionConfig = isset($config['extensions']['config'][$extension])
|
||||
? $config['extensions']['config'][$extension]
|
||||
: [];
|
||||
|
||||
if (!isset($config['extensions']['enabled'])) {
|
||||
return $extensionConfig;
|
||||
}
|
||||
|
||||
if (!is_array($config['extensions']['enabled'])) {
|
||||
return $extensionConfig;
|
||||
}
|
||||
|
||||
foreach ($config['extensions']['enabled'] as $enabledExtensionsConfig) {
|
||||
if (!is_array($enabledExtensionsConfig)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$enabledExtension = key($enabledExtensionsConfig);
|
||||
if ($enabledExtension === $extension) {
|
||||
return Configuration::mergeConfigs(reset($enabledExtensionsConfig), $extensionConfig);
|
||||
}
|
||||
}
|
||||
|
||||
return $extensionConfig;
|
||||
}
|
||||
}
|
||||
21
vendor/codeception/base/src/Codeception/Subscriber/FailFast.php
vendored
Normal file
21
vendor/codeception/base/src/Codeception/Subscriber/FailFast.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace Codeception\Subscriber;
|
||||
|
||||
use Codeception\Event\SuiteEvent;
|
||||
use Codeception\Events;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class FailFast implements EventSubscriberInterface
|
||||
{
|
||||
use Shared\StaticEvents;
|
||||
|
||||
public static $events = [
|
||||
Events::SUITE_BEFORE => 'stopOnFail',
|
||||
];
|
||||
|
||||
public function stopOnFail(SuiteEvent $e)
|
||||
{
|
||||
$e->getResult()->stopOnError(true);
|
||||
$e->getResult()->stopOnFailure(true);
|
||||
}
|
||||
}
|
||||
54
vendor/codeception/base/src/Codeception/Subscriber/GracefulTermination.php
vendored
Normal file
54
vendor/codeception/base/src/Codeception/Subscriber/GracefulTermination.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
declare (ticks = 1);
|
||||
namespace Codeception\Subscriber;
|
||||
|
||||
use Codeception\Event\SuiteEvent;
|
||||
use Codeception\Events;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class GracefulTermination implements EventSubscriberInterface
|
||||
{
|
||||
const SIGNAL_FUNC = 'pcntl_signal';
|
||||
const ASYNC_SIGNAL_HANDLING_FUNC = 'pcntl_async_signals';
|
||||
|
||||
/**
|
||||
* @var SuiteEvent
|
||||
*/
|
||||
protected $suiteEvent;
|
||||
|
||||
public function handleSuite(SuiteEvent $event)
|
||||
{
|
||||
if (PHP_MAJOR_VERSION === 7 && PHP_MINOR_VERSION === 0) {
|
||||
// skip for PHP 7.0: https://github.com/Codeception/Codeception/issues/3607
|
||||
return;
|
||||
}
|
||||
if (function_exists(self::ASYNC_SIGNAL_HANDLING_FUNC)) {
|
||||
pcntl_async_signals(true);
|
||||
}
|
||||
if (function_exists(self::SIGNAL_FUNC)) {
|
||||
pcntl_signal(SIGTERM, [$this, 'terminate']);
|
||||
pcntl_signal(SIGINT, [$this, 'terminate']);
|
||||
}
|
||||
|
||||
$this->suiteEvent = $event;
|
||||
}
|
||||
|
||||
public function terminate()
|
||||
{
|
||||
if ($this->suiteEvent) {
|
||||
$this->suiteEvent->getResult()->stopOnError(true);
|
||||
$this->suiteEvent->getResult()->stopOnFailure(true);
|
||||
}
|
||||
throw new \RuntimeException(
|
||||
"\n\n---------------------------\nTESTS EXECUTION TERMINATED\n---------------------------\n"
|
||||
);
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
if (!function_exists(self::SIGNAL_FUNC)) {
|
||||
return [];
|
||||
}
|
||||
return [Events::SUITE_BEFORE => 'handleSuite'];
|
||||
}
|
||||
}
|
||||
94
vendor/codeception/base/src/Codeception/Subscriber/Module.php
vendored
Normal file
94
vendor/codeception/base/src/Codeception/Subscriber/Module.php
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
namespace Codeception\Subscriber;
|
||||
|
||||
use Codeception\Event\FailEvent;
|
||||
use Codeception\Event\StepEvent;
|
||||
use Codeception\Event\SuiteEvent;
|
||||
use Codeception\Event\TestEvent;
|
||||
use Codeception\Events;
|
||||
use Codeception\Suite;
|
||||
use Codeception\TestInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class Module implements EventSubscriberInterface
|
||||
{
|
||||
use Shared\StaticEvents;
|
||||
|
||||
public static $events = [
|
||||
Events::TEST_BEFORE => 'before',
|
||||
Events::TEST_AFTER => 'after',
|
||||
Events::STEP_BEFORE => 'beforeStep',
|
||||
Events::STEP_AFTER => 'afterStep',
|
||||
Events::TEST_FAIL => 'failed',
|
||||
Events::TEST_ERROR => 'failed',
|
||||
Events::SUITE_BEFORE => 'beforeSuite',
|
||||
Events::SUITE_AFTER => 'afterSuite'
|
||||
];
|
||||
|
||||
protected $modules = [];
|
||||
|
||||
public function beforeSuite(SuiteEvent $e)
|
||||
{
|
||||
$suite = $e->getSuite();
|
||||
if (!$suite instanceof Suite) {
|
||||
return;
|
||||
}
|
||||
$this->modules = $suite->getModules();
|
||||
foreach ($this->modules as $module) {
|
||||
$module->_beforeSuite($e->getSettings());
|
||||
}
|
||||
}
|
||||
|
||||
public function afterSuite()
|
||||
{
|
||||
foreach ($this->modules as $module) {
|
||||
$module->_afterSuite();
|
||||
}
|
||||
}
|
||||
|
||||
public function before(TestEvent $event)
|
||||
{
|
||||
if (!$event->getTest() instanceof TestInterface) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->modules as $module) {
|
||||
$module->_before($event->getTest());
|
||||
}
|
||||
}
|
||||
|
||||
public function after(TestEvent $e)
|
||||
{
|
||||
if (!$e->getTest() instanceof TestInterface) {
|
||||
return;
|
||||
}
|
||||
foreach ($this->modules as $module) {
|
||||
$module->_after($e->getTest());
|
||||
$module->_resetConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public function failed(FailEvent $e)
|
||||
{
|
||||
if (!$e->getTest() instanceof TestInterface) {
|
||||
return;
|
||||
}
|
||||
foreach ($this->modules as $module) {
|
||||
$module->_failed($e->getTest(), $e->getFail());
|
||||
}
|
||||
}
|
||||
|
||||
public function beforeStep(StepEvent $e)
|
||||
{
|
||||
foreach ($this->modules as $module) {
|
||||
$module->_beforeStep($e->getStep(), $e->getTest());
|
||||
}
|
||||
}
|
||||
|
||||
public function afterStep(StepEvent $e)
|
||||
{
|
||||
foreach ($this->modules as $module) {
|
||||
$module->_afterStep($e->getStep(), $e->getTest());
|
||||
}
|
||||
}
|
||||
}
|
||||
44
vendor/codeception/base/src/Codeception/Subscriber/PrepareTest.php
vendored
Normal file
44
vendor/codeception/base/src/Codeception/Subscriber/PrepareTest.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Codeception\Subscriber;
|
||||
|
||||
use Codeception\Event\TestEvent;
|
||||
use Codeception\Events;
|
||||
use Codeception\Lib\Di;
|
||||
use Codeception\Test\Cest;
|
||||
use Codeception\Test\Unit;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class PrepareTest implements EventSubscriberInterface
|
||||
{
|
||||
use Shared\StaticEvents;
|
||||
|
||||
public static $events = [
|
||||
Events::TEST_BEFORE => 'prepare',
|
||||
];
|
||||
|
||||
protected $modules = [];
|
||||
|
||||
public function prepare(TestEvent $event)
|
||||
{
|
||||
$test = $event->getTest();
|
||||
/** @var $di Di **/
|
||||
$prepareMethods = $test->getMetadata()->getParam('prepare');
|
||||
|
||||
if (!$prepareMethods) {
|
||||
return;
|
||||
}
|
||||
$di = $test->getMetadata()->getService('di');
|
||||
|
||||
foreach ($prepareMethods as $method) {
|
||||
|
||||
/** @var $module \Codeception\Module **/
|
||||
if ($test instanceof Cest) {
|
||||
$di->injectDependencies($test->getTestClass(), $method);
|
||||
}
|
||||
if ($test instanceof Unit) {
|
||||
$di->injectDependencies($test, $method);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
5
vendor/codeception/base/src/Codeception/Subscriber/README.md
vendored
Normal file
5
vendor/codeception/base/src/Codeception/Subscriber/README.md
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# Event Listeners (Subscribers)
|
||||
|
||||
Where this is possible Codeception uses the Observer pattern to separate different parts of framework and make them act independently.
|
||||
|
||||
Events are defined in `Codeception\Event`). New features can be added seamlessly when they are created in Subscribers.
|
||||
10
vendor/codeception/base/src/Codeception/Subscriber/Shared/StaticEvents.php
vendored
Normal file
10
vendor/codeception/base/src/Codeception/Subscriber/Shared/StaticEvents.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace Codeception\Subscriber\Shared;
|
||||
|
||||
trait StaticEvents
|
||||
{
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return static::$events;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user