Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: FEATURE: move FlowContextTrait into neos/flow #3181

Closed
wants to merge 1 commit into from

Conversation

mhsdesign
Copy link
Member

Upgrade instructions

Review instructions

Checklist

  • Code follows the PSR-2 coding style
  • Tests have been created, run and adjusted as needed
  • The PR is created against the lowest maintained branch
  • Reviewer - PR Title is brief but complete and starts with FEATURE|TASK|BUGFIX
  • Reviewer - The first section explains the change briefly for change-logs
  • Reviewer - Breaking Changes are marked wit !!! and have upgrade-instructions

@bwaidelich
Copy link
Member

As discussed: I would recommend to keep the neos/behat package, because it is a good starting point and a perfect place for Behat specific documentation and utilities.

But we should radically clean it up for 9.0 with just a simple way to bootstrap Flow via some BehatFlowBootstrapper or a FlowBootstrapTrait along the lines of:

<?php
declare(strict_types=1);

use Doctrine\DBAL\Schema\Schema;
use Neos\Flow\Configuration\ConfigurationManager;
use Neos\Flow\Core\Booting\Exception\SubProcessException;
use Neos\Flow\Core\Booting\Scripts;
use Neos\Flow\Core\Bootstrap;
use Neos\Flow\Exception;
use Neos\Flow\ObjectManagement\ObjectManagerInterface;
use Neos\Flow\Persistence\PersistenceManagerInterface;
use Neos\Flow\Tests\FunctionalTestRequestHandler;

trait FlowContextTrait
{

    /**
     * @var Bootstrap
     */
    private static $bootstrap;

    /**
     * @var Schema
     */
    private static $databaseSchema;

    /**
     * Create a flow bootstrap instance
     * @internal
     */
    private static function initializeFlow(): Bootstrap
    {
        if (self::$bootstrap !== null) {
            // already initialized
            return self::$bootstrap;
        }
        require_once dirname(__DIR__, 5) . '/Packages/Framework/Neos.Flow/Classes/Core/Bootstrap.php';
        if (!defined('FLOW_PATH_ROOT')) {
            define('FLOW_PATH_ROOT', dirname(__DIR__, 5) . '/');
        }
        // The new classloader needs warnings converted to exceptions
        if (!defined('BEHAT_ERROR_REPORTING')) {
            define('BEHAT_ERROR_REPORTING', E_ALL);
        }
        self::$bootstrap = new Bootstrap('Testing/Behat');
        Scripts::initializeClassLoader(self::$bootstrap);
        Scripts::initializeSignalSlot(self::$bootstrap);
        Scripts::initializePackageManagement(self::$bootstrap);
        self::$bootstrap->setActiveRequestHandler(new FunctionalTestRequestHandler(self::$bootstrap));
        self::$bootstrap->buildRuntimeSequence()->invoke(self::$bootstrap);
        return self::$bootstrap;
    }

    /**
     * @AfterSuite
     */
    public static function shutdownFlow(): void
    {
        if (self::$bootstrap !== null) {
            self::$bootstrap->shutdown('Runtime');
        }
    }

    /**
     * Persist any changes
     */
    protected function persistAll(): void
    {
        $this->getObject(PersistenceManagerInterface::class)->persistAll();
        $this->getObject(PersistenceManagerInterface::class)->clearState();
    }

    /**
     * If you only want to get an object instance you can use getObject() instead
     * @see getObject
     *
     * @return ObjectManagerInterface
     */
    protected function getObjectManager(): ObjectManagerInterface
    {
        try {
            return self::initializeFlow()->getObjectManager();
        } catch (Exception $e) {
            throw new \RuntimeException('Could not initialize Flow Object Manager', 1549385035, $e);
        }
    }

    /**
     * @template T of object
     * @param class-string<T> $className
     *
     * @return T
     */
    protected function getObject(string $className): object
    {
        return $this->getObjectManager()->get($className);
    }

    /**
     * Executes the specified $command in the context of the application to test
     */
    protected function executeCommand(string $command, array $commandArguments): void
    {
        /** @var ConfigurationManager $configurationManager */
        $configurationManager = $this->getObject(ConfigurationManager::class);
        /** @noinspection PhpUnhandledExceptionInspection */
        $flowSettings = $configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'Neos.Flow');
        try {
            Scripts::executeCommand($command, $flowSettings, false, $commandArguments);
        } catch (SubProcessException $e) {
            throw new RuntimeException(sprintf('An exception was thrown while executing command "%s"; %s', $command, $e->getMessage()), 1549290029, $e);
        }
    }
}

}

/**
* @AfterSuite
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we switch this to attributes in the future we would create a dependency on behat, therefore I think we want a separate package even if it's just this trait?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yesssesses it’s in neos/be hat already. This idea is overhauled and can be closed. We decided against this.

@mhsdesign mhsdesign closed this Dec 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants