refactor #42 Acceptance tests for core functionalities (bartoszpietrzak1994, pamil)
This PR was merged into the 2.0-dev branch. Discussion ---------- Commits -------742d3358b5Injected parameter test POC7250dfca76Get bare Behat scenario running11f5a326b3Test injecting parametersd4efe9a6dfSimplify services definition in Behat9cede4d612Test injecting servicesd5fcb25ef2Test autowiring contextsb4bcbb1233Test autowired & autoconfigured contextsc8b0cbb205Test isolating contexts6061eaaf62Test Mink integration05f4fe789fApply coding standard fixes4405596ca1Make PHPStan passing85796e2fefFix build on Symfony 3.4
This commit is contained in:
133
features/autowiring_contexts.feature
Normal file
133
features/autowiring_contexts.feature
Normal file
@@ -0,0 +1,133 @@
|
||||
Feature: Autowiring contexts
|
||||
|
||||
Background:
|
||||
Given a working Symfony application with SymfonyExtension configured
|
||||
And a Behat configuration containing:
|
||||
"""
|
||||
default:
|
||||
suites:
|
||||
default:
|
||||
contexts:
|
||||
- App\Tests\SomeContext
|
||||
"""
|
||||
|
||||
Scenario: Autowiring a context with a service
|
||||
Given a feature file containing:
|
||||
"""
|
||||
Feature:
|
||||
Scenario:
|
||||
Then the container should be passed
|
||||
"""
|
||||
And a context file "tests/SomeContext.php" containing:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace App\Tests;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
final class SomeContext implements Context {
|
||||
private $container;
|
||||
|
||||
public function __construct(?ContainerInterface $container = null) { $this->container = $container; }
|
||||
|
||||
/** @Then the container should be passed */
|
||||
public function containerShouldBePassed(): void
|
||||
{
|
||||
assert(is_object($this->container));
|
||||
assert($this->container instanceof ContainerInterface);
|
||||
}
|
||||
}
|
||||
"""
|
||||
And a YAML services file containing:
|
||||
"""
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
|
||||
App\Tests\SomeContext:
|
||||
public: true
|
||||
"""
|
||||
When I run Behat
|
||||
Then it should pass
|
||||
|
||||
Scenario: Autowiring a context with a binding
|
||||
Given a feature file containing:
|
||||
"""
|
||||
Feature:
|
||||
Scenario:
|
||||
Then the passed argument should be "KrzysztofKrawczyk"
|
||||
"""
|
||||
And a context file "tests/SomeContext.php" containing:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace App\Tests;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
|
||||
final class SomeContext implements Context {
|
||||
private $argument;
|
||||
|
||||
public function __construct(?string $argument = null) { $this->argument = $argument; }
|
||||
|
||||
/** @Then the passed argument should be :expected */
|
||||
public function passedArgumentShouldBe(string $expected): void { assert($this->argument === $expected); }
|
||||
}
|
||||
"""
|
||||
And a YAML services file containing:
|
||||
"""
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
bind:
|
||||
$argument: KrzysztofKrawczyk
|
||||
|
||||
App\Tests\SomeContext:
|
||||
public: true
|
||||
"""
|
||||
When I run Behat
|
||||
Then it should pass
|
||||
|
||||
Scenario: Autowiring and autoconfiguring context based on prototype
|
||||
Given a feature file containing:
|
||||
"""
|
||||
Feature:
|
||||
Scenario:
|
||||
Then the container should be passed
|
||||
"""
|
||||
And a context file "tests/SomeContext.php" containing:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace App\Tests;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
final class SomeContext implements Context {
|
||||
private $container;
|
||||
|
||||
public function __construct(?ContainerInterface $container = null) { $this->container = $container; }
|
||||
|
||||
/** @Then the container should be passed */
|
||||
public function containerShouldBePassed(): void
|
||||
{
|
||||
assert(is_object($this->container));
|
||||
assert($this->container instanceof ContainerInterface);
|
||||
}
|
||||
}
|
||||
"""
|
||||
And a YAML services file containing:
|
||||
"""
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
App\Tests\:
|
||||
resource: '../tests/*'
|
||||
"""
|
||||
When I run Behat
|
||||
Then it should pass
|
||||
61
features/injecting_parameters_into_context.feature
Normal file
61
features/injecting_parameters_into_context.feature
Normal file
@@ -0,0 +1,61 @@
|
||||
Feature: Injecting parameters into context
|
||||
|
||||
Background:
|
||||
Given a working Symfony application with SymfonyExtension configured
|
||||
And a Behat configuration containing:
|
||||
"""
|
||||
default:
|
||||
suites:
|
||||
default:
|
||||
contexts:
|
||||
- App\Tests\SomeContext
|
||||
"""
|
||||
And a feature file containing:
|
||||
"""
|
||||
Feature:
|
||||
Scenario:
|
||||
Then the passed parameter should be "test"
|
||||
"""
|
||||
And a context file "tests/SomeContext.php" containing:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace App\Tests;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
|
||||
final class SomeContext implements Context {
|
||||
private $parameter;
|
||||
|
||||
public function __construct(?string $parameter = null) { $this->parameter = $parameter; }
|
||||
|
||||
/** @Then the passed parameter should be :expected */
|
||||
public function parameterShouldBe(string $expected): void { assert($this->parameter === $expected); }
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: Injecting a parameter into a context explicitly set as public
|
||||
Given a YAML services file containing:
|
||||
"""
|
||||
services:
|
||||
App\Tests\SomeContext:
|
||||
public: true
|
||||
arguments:
|
||||
- "%kernel.environment%"
|
||||
"""
|
||||
When I run Behat
|
||||
Then it should pass
|
||||
|
||||
Scenario: Injecting a parameter into an autoconfigured context
|
||||
Given a YAML services file containing:
|
||||
"""
|
||||
services:
|
||||
_defaults:
|
||||
autoconfigure: true
|
||||
|
||||
App\Tests\SomeContext:
|
||||
arguments:
|
||||
- "%kernel.environment%"
|
||||
"""
|
||||
When I run Behat
|
||||
Then it should pass
|
||||
65
features/injecting_services_into_context.feature
Normal file
65
features/injecting_services_into_context.feature
Normal file
@@ -0,0 +1,65 @@
|
||||
Feature: Injecting services into context
|
||||
|
||||
Background:
|
||||
Given a working Symfony application with SymfonyExtension configured
|
||||
And a Behat configuration containing:
|
||||
"""
|
||||
default:
|
||||
suites:
|
||||
default:
|
||||
contexts:
|
||||
- App\Tests\SomeContext
|
||||
"""
|
||||
And a feature file containing:
|
||||
"""
|
||||
Feature:
|
||||
Scenario:
|
||||
Then the passed service should be an instance of "\Psr\Container\ContainerInterface"
|
||||
"""
|
||||
And a context file "tests/SomeContext.php" containing:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace App\Tests;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
|
||||
final class SomeContext implements Context {
|
||||
private $service;
|
||||
|
||||
public function __construct($service = null) { $this->service = $service; }
|
||||
|
||||
/** @Then the passed service should be an instance of :expected */
|
||||
public function serviceShouldBe(string $expected): void
|
||||
{
|
||||
assert(is_object($this->service));
|
||||
assert($this->service instanceof $expected);
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: Injecting a service into a context explicitly set as public
|
||||
Given a YAML services file containing:
|
||||
"""
|
||||
services:
|
||||
App\Tests\SomeContext:
|
||||
public: true
|
||||
arguments:
|
||||
- "@service_container"
|
||||
"""
|
||||
When I run Behat
|
||||
Then it should pass
|
||||
|
||||
Scenario: Injecting a service into an autoconfigured context
|
||||
Given a YAML services file containing:
|
||||
"""
|
||||
services:
|
||||
_defaults:
|
||||
autoconfigure: true
|
||||
|
||||
App\Tests\SomeContext:
|
||||
arguments:
|
||||
- "@service_container"
|
||||
"""
|
||||
When I run Behat
|
||||
Then it should pass
|
||||
54
features/isolating_contexts.feature
Normal file
54
features/isolating_contexts.feature
Normal file
@@ -0,0 +1,54 @@
|
||||
Feature: Isolating contexts
|
||||
|
||||
Scenario: Keeping contexts isolated between scenarios
|
||||
Given a working Symfony application with SymfonyExtension configured
|
||||
And a Behat configuration containing:
|
||||
"""
|
||||
default:
|
||||
suites:
|
||||
default:
|
||||
contexts:
|
||||
- App\Tests\SomeContext
|
||||
"""
|
||||
And a feature file containing:
|
||||
"""
|
||||
Feature:
|
||||
Scenario: First scenario
|
||||
Then the property should be "shit happens"
|
||||
|
||||
Scenario: Second scenario
|
||||
When I change the property to "shit does not happen"
|
||||
Then the property should be "shit does not happen"
|
||||
|
||||
Scenario: Third scenario
|
||||
Then the property should be "shit happens"
|
||||
"""
|
||||
And a context file "tests/SomeContext.php" containing:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace App\Tests;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
final class SomeContext implements Context {
|
||||
private $property = 'shit happens';
|
||||
|
||||
public function __construct(?ContainerInterface $container = null) { $this->container = $container; }
|
||||
|
||||
/** @When I change the property to :value */
|
||||
public function changeProperty(string $value): void { $this->property = $value; }
|
||||
|
||||
/** @Then the property should be :expected*/
|
||||
public function propertyShouldBe(string $expected): void { assert($this->property === $expected); }
|
||||
}
|
||||
"""
|
||||
And a YAML services file containing:
|
||||
"""
|
||||
services:
|
||||
App\Tests\SomeContext:
|
||||
public: true
|
||||
"""
|
||||
When I run Behat
|
||||
Then it should pass
|
||||
107
features/mink_integration.feature
Normal file
107
features/mink_integration.feature
Normal file
@@ -0,0 +1,107 @@
|
||||
Feature: Mink integration
|
||||
|
||||
Background:
|
||||
Given a working Symfony application with SymfonyExtension configured
|
||||
And a Behat configuration containing:
|
||||
"""
|
||||
default:
|
||||
extensions:
|
||||
Behat\MinkExtension:
|
||||
base_url: "http://localhost:8080/"
|
||||
default_session: symfony
|
||||
sessions:
|
||||
symfony:
|
||||
symfony: ~
|
||||
suites:
|
||||
default:
|
||||
contexts:
|
||||
- App\Tests\SomeContext
|
||||
"""
|
||||
And a feature file containing:
|
||||
"""
|
||||
Feature:
|
||||
Scenario:
|
||||
When I visit the page "/hello-world"
|
||||
Then I should see "Hello world!" on the page
|
||||
And the base url from Mink parameters should be "http://localhost:8080/"
|
||||
|
||||
# Doubling the scenario to account for some weird error connected to Mink's session
|
||||
Scenario:
|
||||
When I visit the page "/hello-world"
|
||||
Then I should see "Hello world!" on the page
|
||||
And the base url from Mink parameters should be "http://localhost:8080/"
|
||||
"""
|
||||
And a context file "tests/SomeContext.php" containing:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace App\Tests;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
use Behat\Mink\Session;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
final class SomeContext implements Context {
|
||||
private $session;
|
||||
private $parameters;
|
||||
|
||||
public function __construct(Session $session, $minkParameters)
|
||||
{
|
||||
if (!is_array($minkParameters) && !$minkParameters instanceof \ArrayAccess) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'"$parameters" passed to "%s" has to be an array or implement "%s".',
|
||||
self::class,
|
||||
\ArrayAccess::class
|
||||
));
|
||||
}
|
||||
|
||||
$this->session = $session;
|
||||
$this->parameters = $minkParameters;
|
||||
}
|
||||
|
||||
/** @When I visit the page :page */
|
||||
public function visitPage(string $page): void
|
||||
{
|
||||
$this->session->visit($page);
|
||||
}
|
||||
|
||||
/** @Then I should see :content on the page */
|
||||
public function shouldSeeContentOnPage(string $content): void
|
||||
{
|
||||
assert(false !== strpos($this->session->getPage()->getContent(), $content));
|
||||
}
|
||||
|
||||
/** @Then the base url from Mink parameters should be :expected */
|
||||
public function baseUrlShouldBe(string $expected): void
|
||||
{
|
||||
assert(isset($this->parameters['base_url']));
|
||||
assert($this->parameters['base_url'] === $expected);
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: Injecting Mink session and Mink parameters
|
||||
Given a YAML services file containing:
|
||||
"""
|
||||
services:
|
||||
App\Tests\SomeContext:
|
||||
public: true
|
||||
arguments:
|
||||
- '@behat.mink.default_session'
|
||||
- '@behat.mink.parameters'
|
||||
"""
|
||||
When I run Behat
|
||||
Then it should pass
|
||||
|
||||
Scenario: Autowiring and autoconfiguring Mink session and Mink parameters
|
||||
Given a YAML services file containing:
|
||||
"""
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
App\Tests\SomeContext: ~
|
||||
"""
|
||||
When I run Behat
|
||||
Then it should pass
|
||||
@@ -1,9 +1,33 @@
|
||||
Feature: Running bare Behat scenarios
|
||||
|
||||
Scenario: Running Behat with SymfonyExtension
|
||||
Given a Behat configuration with the minimal working configuration for SymfonyExtension
|
||||
And a Behat configuration with the minimal working configuration for MinkExtension
|
||||
And an application kernel with the minimal working configuration for SymfonyExtension
|
||||
And a feature file with passing scenario
|
||||
Given a working Symfony application with SymfonyExtension configured
|
||||
And a Behat configuration containing:
|
||||
"""
|
||||
default:
|
||||
suites:
|
||||
default:
|
||||
contexts:
|
||||
- App\Tests\SomeContext
|
||||
"""
|
||||
And a feature file containing:
|
||||
"""
|
||||
Feature:
|
||||
Scenario:
|
||||
Then it should pass
|
||||
"""
|
||||
And a context file "tests/SomeContext.php" containing:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace App\Tests;
|
||||
|
||||
use Behat\Behat\Context\Context;
|
||||
|
||||
final class SomeContext implements Context {
|
||||
/** @Then it should pass */
|
||||
public function itShouldPass(): void {}
|
||||
}
|
||||
"""
|
||||
When I run Behat
|
||||
Then it should pass
|
||||
|
||||
@@ -2,4 +2,7 @@ parameters:
|
||||
reportUnmatchedIgnoredErrors: false
|
||||
|
||||
ignoreErrors:
|
||||
- '/Cannot access offset 0 on callable\./'
|
||||
- '/Cannot access offset 1 on callable\./'
|
||||
- '/Method FriendsOfBehat\\SymfonyExtension\\Context\\Environment\\InitialisedContextServiceEnvironment::bindCallee\(\) should return callable/'
|
||||
- '/Cannot call method [a-zA-Z0-9]+\(\) on Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface|null\./'
|
||||
|
||||
@@ -24,6 +24,9 @@ final class FriendsOfBehatSymfonyExtensionExtension extends Extension implements
|
||||
$container
|
||||
->registerForAutoconfiguration(Context::class)
|
||||
->addTag('fob.context')
|
||||
->setBindings([
|
||||
'$minkParameters' => new Reference('behat.mink.parameters'),
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,11 +60,12 @@ final class ContextServiceEnvironmentHandler implements EnvironmentHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UninitialisedContextServiceEnvironment $uninitializedEnvironment
|
||||
*
|
||||
* @throws EnvironmentIsolationException
|
||||
*/
|
||||
public function isolateEnvironment(Environment $uninitializedEnvironment, $testSubject = null): Environment
|
||||
{
|
||||
/** @var UninitialisedContextServiceEnvironment $uninitializedEnvironment */
|
||||
$this->assertEnvironmentCanBeIsolated($uninitializedEnvironment, $testSubject);
|
||||
|
||||
$environment = new InitialisedContextServiceEnvironment($uninitializedEnvironment->getSuite());
|
||||
@@ -136,22 +137,31 @@ final class ContextServiceEnvironmentHandler implements EnvironmentHandler
|
||||
return $class;
|
||||
}
|
||||
|
||||
throw new \Exception('wtf?');
|
||||
throw new \DomainException(sprintf('There is no service or class "%s".', $contextId));
|
||||
}
|
||||
|
||||
private function getContext(string $contextId): Context
|
||||
{
|
||||
if ($this->getContainer()->has($contextId)) {
|
||||
return $this->getContainer()->get($contextId);
|
||||
}
|
||||
|
||||
$class = '\\' . ltrim($contextId, '\\');
|
||||
|
||||
if (class_exists($class)) {
|
||||
return new $class();
|
||||
if ($this->getContainer()->has($contextId)) {
|
||||
$context = $this->getContainer()->get($contextId);
|
||||
} elseif (class_exists($class)) {
|
||||
$context = new $class();
|
||||
} else {
|
||||
throw new \DomainException(sprintf('There is no service or class "%s".', $contextId));
|
||||
}
|
||||
|
||||
throw new \Exception('wtf?');
|
||||
if (!$context instanceof Context) {
|
||||
throw new \DomainException(sprintf(
|
||||
'Context "%s" referenced as "%s" needs to implement "%s".',
|
||||
get_class($context),
|
||||
$contextId,
|
||||
Context::class
|
||||
));
|
||||
}
|
||||
|
||||
return $context;
|
||||
}
|
||||
|
||||
private function getContainer(): ContainerInterface
|
||||
|
||||
@@ -22,6 +22,16 @@ final class SymfonyDriver extends BrowserKitDriver
|
||||
));
|
||||
}
|
||||
|
||||
parent::__construct($kernel->getContainer()->get('test.client'), $baseUrl);
|
||||
$testClient = $kernel->getContainer()->get('test.client');
|
||||
|
||||
if (!$testClient instanceof Client) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
'Service "test.client" should be an instance of "%s", "%s" given.',
|
||||
Client::class,
|
||||
get_class($testClient)
|
||||
));
|
||||
}
|
||||
|
||||
parent::__construct($testClient, $baseUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ final class SymfonyExtension implements Extension
|
||||
*/
|
||||
private const DRIVER_KERNEL_ID = 'fob_symfony.driver_kernel';
|
||||
|
||||
/** @var bool */
|
||||
private $minkExtensionFound = false;
|
||||
|
||||
public function getConfigKey(): string
|
||||
{
|
||||
return 'fob_symfony';
|
||||
@@ -43,7 +46,14 @@ final class SymfonyExtension implements Extension
|
||||
|
||||
public function initialize(ExtensionManager $extensionManager): void
|
||||
{
|
||||
$this->registerSymfonyDriverFactory($extensionManager);
|
||||
/** @var MinkExtension|null $minkExtension */
|
||||
$minkExtension = $extensionManager->getExtension('mink');
|
||||
if (null === $minkExtension) {
|
||||
return;
|
||||
}
|
||||
|
||||
$minkExtension->registerDriverFactory(new SymfonyDriverFactory('symfony', new Reference(self::DRIVER_KERNEL_ID)));
|
||||
$this->minkExtensionFound = true;
|
||||
}
|
||||
|
||||
public function configure(ArrayNodeDefinition $builder): void
|
||||
@@ -75,9 +85,11 @@ final class SymfonyExtension implements Extension
|
||||
|
||||
$this->loadEnvironmentHandler($container);
|
||||
|
||||
if ($this->minkExtensionFound) {
|
||||
$this->loadMinkDefaultSession($container);
|
||||
$this->loadMinkParameters($container);
|
||||
}
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container): void
|
||||
{
|
||||
@@ -166,15 +178,4 @@ final class SymfonyExtension implements Extension
|
||||
|
||||
$container->setDefinition('fob_symfony.mink.parameters', $minkParametersDefinition);
|
||||
}
|
||||
|
||||
private function registerSymfonyDriverFactory(ExtensionManager $extensionManager): void
|
||||
{
|
||||
/** @var MinkExtension|null $minkExtension */
|
||||
$minkExtension = $extensionManager->getExtension('mink');
|
||||
if (null === $minkExtension) {
|
||||
return;
|
||||
}
|
||||
|
||||
$minkExtension->registerDriverFactory(new SymfonyDriverFactory('symfony', new Reference(self::DRIVER_KERNEL_ID)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,24 +12,16 @@ use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
final class TestContext implements Context
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string */
|
||||
private static $workingDir;
|
||||
|
||||
/**
|
||||
* @var Filesystem
|
||||
*/
|
||||
/** @var Filesystem */
|
||||
private static $filesystem;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string */
|
||||
private static $phpBin;
|
||||
|
||||
/**
|
||||
* @var Process
|
||||
*/
|
||||
/** @var Process */
|
||||
private $process;
|
||||
|
||||
/**
|
||||
@@ -59,13 +51,98 @@ final class TestContext implements Context
|
||||
self::$filesystem->remove(self::$workingDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given a working Symfony application with SymfonyExtension configured
|
||||
*/
|
||||
public function workingSymfonyApplicationWithExtension(): void
|
||||
{
|
||||
$this->thereIsConfiguration(<<<'CON'
|
||||
default:
|
||||
extensions:
|
||||
FriendsOfBehat\SymfonyExtension:
|
||||
kernel:
|
||||
class: App\Kernel
|
||||
CON
|
||||
);
|
||||
|
||||
$this->thereIsFile('vendor/autoload.php', sprintf(<<<'CON'
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$loader = require '%s';
|
||||
$loader->addPsr4('App\\', __DIR__ . '/../src/');
|
||||
$loader->addPsr4('App\\Tests\\', __DIR__ . '/../tests/');
|
||||
|
||||
return $loader;
|
||||
CON
|
||||
, __DIR__ . '/../../../vendor/autoload.php'));
|
||||
|
||||
$this->thereIsFile('src/Kernel.php', <<<'CON'
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Kernel as HttpKernel;
|
||||
use Symfony\Component\Routing\RouteCollectionBuilder;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
use MicroKernelTrait;
|
||||
|
||||
public function helloWorld(): Response
|
||||
{
|
||||
return new Response('Hello world!');
|
||||
}
|
||||
|
||||
public function registerBundles(): iterable
|
||||
{
|
||||
return [
|
||||
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
|
||||
new \FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
|
||||
{
|
||||
$container->loadFromExtension('framework', [
|
||||
'test' => $this->getEnvironment() === 'test',
|
||||
'secret' => 'Pigeon',
|
||||
]);
|
||||
|
||||
$loader->load(__DIR__ . '/../config/services.yaml');
|
||||
}
|
||||
|
||||
protected function configureRoutes(RouteCollectionBuilder $routes)
|
||||
{
|
||||
$routes->add('/hello-world', 'kernel:helloWorld');
|
||||
}
|
||||
}
|
||||
CON
|
||||
);
|
||||
|
||||
$this->thereIsFile('config/services.yaml', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^a YAML services file containing:$/
|
||||
*/
|
||||
public function yamlServicesFile($content): void
|
||||
{
|
||||
$this->thereIsFile('config/services.yaml', (string) $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^a Behat configuration containing(?: "([^"]+)"|:)$/
|
||||
*/
|
||||
public function thereIsConfiguration($content): void
|
||||
{
|
||||
$mainConfigFile = sprintf('%s/behat.yml', self::$workingDir);
|
||||
$newConfigFile = sprintf('%s/behat-%s.yml', self::$workingDir, md5($content));
|
||||
$newConfigFile = sprintf('%s/behat-%s.yml', self::$workingDir, md5((string) $content));
|
||||
|
||||
self::$filesystem->dumpFile($newConfigFile, (string) $content);
|
||||
|
||||
@@ -79,40 +156,6 @@ final class TestContext implements Context
|
||||
self::$filesystem->dumpFile($mainConfigFile, Yaml::dump($mainBehatConfiguration));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^a Behat configuration with the minimal working configuration for SymfonyExtension$/
|
||||
*/
|
||||
public function thereIsConfigurationWithMinimalWorkingConfigurationForSymfonyExtension(): void
|
||||
{
|
||||
$this->thereIsConfiguration(<<<'CON'
|
||||
default:
|
||||
extensions:
|
||||
FriendsOfBehat\SymfonyExtension:
|
||||
kernel:
|
||||
path: app/AppKernel.php
|
||||
class: AppKernel
|
||||
CON
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^a Behat configuration with the minimal working configuration for MinkExtension$/
|
||||
*/
|
||||
public function thereIsConfigurationWithMinimalWorkingConfigurationForMinkExtension(): void
|
||||
{
|
||||
$this->thereIsConfiguration(<<<'CON'
|
||||
default:
|
||||
extensions:
|
||||
Behat\MinkExtension:
|
||||
base_url: "http://localhost:8080/"
|
||||
default_session: symfony
|
||||
sessions:
|
||||
symfony:
|
||||
symfony: ~
|
||||
CON
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^a (?:.+ |)file "([^"]+)" containing(?: "([^"]+)"|:)$/
|
||||
*/
|
||||
@@ -121,42 +164,6 @@ CON
|
||||
self::$filesystem->dumpFile(self::$workingDir . '/' . $file, (string) $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^an application kernel with the minimal working configuration for SymfonyExtension$/
|
||||
*/
|
||||
public function thereIsKernelWithMinimalWorkingConfiguration(): void
|
||||
{
|
||||
$this->thereIsFile('app/AppKernel.php', <<<'CON'
|
||||
<?php
|
||||
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||
|
||||
class AppKernel extends Kernel
|
||||
{
|
||||
public function registerBundles()
|
||||
{
|
||||
return [
|
||||
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
|
||||
new \FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle(),
|
||||
];
|
||||
}
|
||||
|
||||
public function registerContainerConfiguration(LoaderInterface $loader)
|
||||
{
|
||||
$loader->load(function (ContainerBuilder $container): void {
|
||||
$container->loadFromExtension('framework', [
|
||||
'test' => $this->getEnvironment() === 'test',
|
||||
'secret' => 'Pigeon',
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
CON
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^a feature file containing(?: "([^"]+)"|:)$/
|
||||
*/
|
||||
@@ -165,110 +172,6 @@ CON
|
||||
$this->thereIsFile(sprintf('features/%s.feature', md5(uniqid('', true))), $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^a feature file with passing scenario$/
|
||||
*/
|
||||
public function thereIsFeatureFileWithPassingScenario(): void
|
||||
{
|
||||
$this->thereIsFile('features/bootstrap/FeatureContext.php', <<<'CON'
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
class FeatureContext implements \Behat\Behat\Context\Context
|
||||
{
|
||||
/** @Then it passes */
|
||||
public function itPasses() {}
|
||||
}
|
||||
CON
|
||||
);
|
||||
|
||||
$this->thereIsFeatureFile(<<<FEA
|
||||
Feature: Passing feature
|
||||
|
||||
Scenario: Passing scenario
|
||||
Then it passes
|
||||
FEA
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^a feature file with failing scenario$/
|
||||
*/
|
||||
public function thereIsFeatureFileWithFailingScenario(): void
|
||||
{
|
||||
$this->thereIsFile('features/bootstrap/FeatureContext.php', <<<'CON'
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
class FeatureContext implements \Behat\Behat\Context\Context
|
||||
{
|
||||
/** @Then it fails */
|
||||
public function itFails() { throw new \RuntimeException(); }
|
||||
}
|
||||
CON
|
||||
);
|
||||
|
||||
$this->thereIsFeatureFile(<<<FEA
|
||||
Feature: Failing feature
|
||||
|
||||
Scenario: Failing scenario
|
||||
Then it fails
|
||||
FEA
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^a feature file with scenario with missing step$/
|
||||
*/
|
||||
public function thereIsFeatureFileWithScenarioWithMissingStep(): void
|
||||
{
|
||||
$this->thereIsFile('features/bootstrap/FeatureContext.php', <<<'CON'
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
class FeatureContext implements \Behat\Behat\Context\Context {}
|
||||
CON
|
||||
);
|
||||
|
||||
$this->thereIsFeatureFile(<<<FEA
|
||||
Feature: Feature with missing step
|
||||
|
||||
Scenario: Scenario with missing step
|
||||
Then it does not have this step
|
||||
FEA
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Given /^a feature file with scenario with pending step$/
|
||||
*/
|
||||
public function thereIsFeatureFileWithScenarioWithPendingStep(): void
|
||||
{
|
||||
$this->thereIsFile('features/bootstrap/FeatureContext.php', <<<'CON'
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
class FeatureContext implements \Behat\Behat\Context\Context
|
||||
{
|
||||
/** @Then it has this step as pending */
|
||||
public function itFails() { throw new \Behat\Behat\Tester\Exception\PendingException(); }
|
||||
}
|
||||
CON
|
||||
);
|
||||
|
||||
$this->thereIsFeatureFile(<<<FEA
|
||||
Feature: Feature with pending step
|
||||
|
||||
Scenario: Scenario with pending step
|
||||
Then it has this step as pending
|
||||
FEA
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /^I run Behat$/
|
||||
*/
|
||||
@@ -290,7 +193,7 @@ FEA
|
||||
}
|
||||
|
||||
throw new \DomainException(
|
||||
'Behat was expecting to pass, but failed with the following output:' . PHP_EOL . PHP_EOL . $this->getProcessOutput()
|
||||
'Behat was expecting to pass, but failed with the following output:' . \PHP_EOL . \PHP_EOL . $this->getProcessOutput()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -313,7 +216,7 @@ FEA
|
||||
}
|
||||
|
||||
throw new \DomainException(
|
||||
'Behat was expecting to fail, but passed with the following output:' . PHP_EOL . PHP_EOL . $this->getProcessOutput()
|
||||
'Behat was expecting to fail, but passed with the following output:' . \PHP_EOL . \PHP_EOL . $this->getProcessOutput()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -349,16 +252,13 @@ FEA
|
||||
|
||||
if (0 === $result) {
|
||||
throw new \DomainException(sprintf(
|
||||
'Pattern "%s" does not match the following output:' . PHP_EOL . PHP_EOL . '%s',
|
||||
'Pattern "%s" does not match the following output:' . \PHP_EOL . \PHP_EOL . '%s',
|
||||
$pattern,
|
||||
$output
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getProcessOutput(): string
|
||||
{
|
||||
$this->assertProcessIsAvailable();
|
||||
@@ -366,9 +266,6 @@ FEA
|
||||
return $this->process->getErrorOutput() . $this->process->getOutput();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function getProcessExitCode(): int
|
||||
{
|
||||
$this->assertProcessIsAvailable();
|
||||
@@ -387,8 +284,6 @@ FEA
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
private static function findPhpBinary(): string
|
||||
|
||||
Reference in New Issue
Block a user