Initial commit

This commit is contained in:
Kamil Kokot
2016-07-23 01:19:00 +02:00
commit ef4928c2ee
11 changed files with 442 additions and 0 deletions

4
.gitattributes vendored Normal file
View File

@@ -0,0 +1,4 @@
/.gitattributes export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
/behat.yml.dist export-ignore

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/vendor
/behat.yml
/composer.lock

32
.travis.yml Normal file
View File

@@ -0,0 +1,32 @@
language: php
php:
- 7.0
- 5.6
env:
global:
- COMPOSER_OPTIONS=""
matrix:
include:
-
php: 5.6
env: COMPOSER_OPTIONS="--prefer-lowest"
cache:
directories:
- vendor
before_install:
- phpenv config-rm xdebug.ini || true
- composer self-update
install:
- composer update --prefer-dist $COMPOSER_OPTIONS
script:
- composer validate --strict
- vendor/bin/behat --strict

19
LICENSE Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2016 Kamil Kokot
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

22
README.md Normal file
View File

@@ -0,0 +1,22 @@
# Symfony Extension [![License](https://img.shields.io/packagist/l/friends-of-behat/symfony-extension.svg)](https://packagist.org/packages/friends-of-behat/symfony-extension) [![Version](https://img.shields.io/packagist/v/friends-of-behat/symfony-extension.svg)](https://packagist.org/packages/friends-of-behat/symfony-extension) [![Build status on Linux](https://img.shields.io/travis/FriendsOfBehat/SymfonyExtension/master.svg)](http://travis-ci.org/FriendsOfBehat/SymfonyExtension) [![Scrutinizer Quality Score](https://img.shields.io/scrutinizer/g/FriendsOfBehat/SymfonyExtension.svg)](https://scrutinizer-ci.com/g/FriendsOfBehat/SymfonyExtension/)
Integrates Behat with Symfony (both 2 and 3).
## Usage
1. Install it:
```bash
$ composer require friends-of-behat/symfony-extension --dev
```
2. Enable and configure in your Behat configuration:
```yaml
default:
# ...
extensions:
FriendsOfBehat\SymfonyExtension: Z
```
3. Good luck & have fun!

3
behat.yml.dist Normal file
View File

@@ -0,0 +1,3 @@
default:
extensions:
FriendsOfBehat\SymfonyExtension: ~

26
composer.json Normal file
View File

@@ -0,0 +1,26 @@
{
"name": "friends-of-behat/symfony-extension",
"description": "Allows to overwrite suites' default settings.",
"license": "MIT",
"authors": [
{
"name": "Kamil Kokot",
"email": "kamil@kokot.me",
"homepage": "http://kamil.kokot.me"
}
],
"require": {
"php": "^5.6|^7.0",
"behat/behat": "^3.1",
"symfony/http-kernel": "^2.7|^3.0"
},
"require-dev": {
"behat/mink": "^1.7",
"behat/mink-browserkit-driver": "^1.3",
"behat/mink-extension": "^2.2"
},
"autoload": {
"psr-4": { "FriendsOfBehat\\SymfonyExtension\\": "src/" }
}
}

View File

@@ -0,0 +1,70 @@
<?php
namespace FriendsOfBehat\SymfonyExtension\Driver\Factory;
use Behat\MinkExtension\ServiceContainer\Driver\DriverFactory;
use FriendsOfBehat\SymfonyExtension\Driver\SymfonyDriver;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
/**
* @author Kamil Kokot <kamil@kokot.me>
*/
final class SymfonyDriverFactory implements DriverFactory
{
/**
* @var string
*/
private $name;
/**
* @var Reference
*/
private $kernel;
/**
* @param string $name
* @param Reference $kernel
*/
public function __construct($name, Reference $kernel)
{
$this->name = $name;
$this->kernel = $kernel;
}
/**
* {@inheritdoc}
*/
public function getDriverName()
{
return $this->name;
}
/**
* {@inheritdoc}
*/
public function supportsJavascript()
{
return false;
}
/**
* {@inheritdoc}
*/
public function configure(ArrayNodeDefinition $builder)
{
}
/**
* {@inheritdoc}
*/
public function buildDriver(array $config)
{
return new Definition(SymfonyDriver::class, [
$this->kernel,
'%mink.base_url%',
]);
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace FriendsOfBehat\SymfonyExtension\Driver;
use Behat\Mink\Driver\BrowserKitDriver;
use Symfony\Component\HttpKernel\KernelInterface;
/**
* @author Kamil Kokot <kamil@kokot.me>
*/
final class SymfonyDriver extends BrowserKitDriver
{
/**
* @param KernelInterface $kernel
* @param string $baseUrl
*/
public function __construct(KernelInterface $kernel, $baseUrl)
{
parent::__construct($kernel->getContainer()->get('test.client'), $baseUrl);
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace FriendsOfBehat\SymfonyExtension\Listener;
use Behat\Behat\EventDispatcher\Event\ExampleTested;
use Behat\Behat\EventDispatcher\Event\ScenarioTested;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelInterface;
/**
* @author Kamil Kokot <kamil@kokot.me>
*/
final class KernelRebooter implements EventSubscriberInterface
{
/**
* @var KernelInterface
*/
private $kernel;
/**
* @param KernelInterface $kernel
*/
public function __construct(KernelInterface $kernel)
{
$this->kernel = $kernel;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
ScenarioTested::AFTER => ['rebootKernel', -15],
ExampleTested::AFTER => ['rebootKernel', -15],
];
}
public function rebootKernel()
{
$this->kernel->shutdown();
$this->kernel->boot();
}
}

View File

@@ -0,0 +1,197 @@
<?php
namespace FriendsOfBehat\SymfonyExtension\ServiceContainer;
use Behat\MinkExtension\ServiceContainer\MinkExtension;
use Behat\Testwork\EventDispatcher\ServiceContainer\EventDispatcherExtension;
use Behat\Testwork\ServiceContainer\Extension;
use Behat\Testwork\ServiceContainer\ExtensionManager;
use FriendsOfBehat\SymfonyExtension\Driver\Factory\SymfonyDriverFactory;
use FriendsOfBehat\SymfonyExtension\Listener\KernelRebooter;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
/**
* @author Kamil Kokot <kamil@kokot.me>
*/
final class SymfonyExtension implements Extension
{
/**
* Kernel used inside Behat contexts or to create services injected to them.
* Container is built before every scenario.
*/
const KERNEL_ID = 'sylius_symfony_extension.kernel';
/**
* The current container used in scenario contexts.
* To be used as a factory for current injected application services.
*/
const KERNEL_CONTAINER_ID = 'sylius_symfony_extension.kernel.container';
/**
* Kernel used by Symfony2 driver to isolate web container from contexts' container.
* Container is built before every request.
*/
const DRIVER_KERNEL_ID = 'sylius_symfony_extension.driver_kernel';
/**
* Kernel that should be used by extensions only.
* Container is built only once at the first use.
*/
const SHARED_KERNEL_ID = 'sylius_symfony_extension.shared_kernel';
/**
* The only container built by shared kernel.
* To be used as a factory for shared injected application services.
*/
const SHARED_KERNEL_CONTAINER_ID = 'sylius_symfony_extension.shared_kernel.container';
/**
* {@inheritdoc}
*/
public function getConfigKey()
{
return 'fob_symfony';
}
/**
* {@inheritdoc}
*/
public function initialize(ExtensionManager $extensionManager)
{
$this->registerSymfonyDriverFactory($extensionManager);
}
/**
* {@inheritdoc}
*/
public function configure(ArrayNodeDefinition $builder)
{
$builder
->addDefaultsIfNotSet()
->children()
->arrayNode('kernel')
->addDefaultsIfNotSet()
->children()
->scalarNode('bootstrap')->defaultValue('app/autoload.php')->end()
->scalarNode('path')->defaultValue('app/AppKernel.php')->end()
->scalarNode('class')->defaultValue('AppKernel')->end()
->scalarNode('env')->defaultValue('test')->end()
->booleanNode('debug')->defaultTrue()->end()
;
}
/**
* {@inheritdoc}
*/
public function load(ContainerBuilder $container, array $config)
{
$this->loadKernel($container, $config['kernel']);
$this->loadKernelContainer($container);
$this->loadDriverKernel($container);
$this->loadSharedKernel($container);
$this->loadSharedKernelContainer($container);
$this->loadKernelRebooter($container);
}
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
}
/**
* @param ContainerBuilder $container
*/
private function loadKernel(ContainerBuilder $container, array $config)
{
$definition = new Definition($config['class'], array(
$config['env'],
$config['debug'],
));
$definition->addMethodCall('boot');
$container->setDefinition(self::KERNEL_ID, $definition);
$container->setParameter(self::KERNEL_ID . '.path', $config['path']);
$container->setParameter(self::KERNEL_ID . '.bootstrap', $config['bootstrap']);
}
/**
* @param ContainerBuilder $container
*/
private function loadKernelContainer(ContainerBuilder $container)
{
$containerDefinition = new Definition(Container::class);
$containerDefinition->setFactory([
new Reference(self::KERNEL_ID),
'getContainer',
]);
$container->setDefinition(self::KERNEL_CONTAINER_ID, $containerDefinition);
}
/**
* @param ContainerBuilder $container
*/
private function loadDriverKernel(ContainerBuilder $container)
{
$container->setDefinition(self::DRIVER_KERNEL_ID, $container->findDefinition(self::KERNEL_ID));
}
/**
* @param ContainerBuilder $container
*/
private function loadSharedKernel(ContainerBuilder $container)
{
$container->setDefinition(self::SHARED_KERNEL_ID, $container->findDefinition(self::KERNEL_ID));
}
/**
* @param ContainerBuilder $container
*/
private function loadSharedKernelContainer(ContainerBuilder $container)
{
$containerDefinition = new Definition(Container::class);
$containerDefinition->setFactory([
new Reference(self::SHARED_KERNEL_ID),
'getContainer',
]);
$container->setDefinition(self::SHARED_KERNEL_CONTAINER_ID, $containerDefinition);
}
/**
* @param ContainerBuilder $container
*/
private function loadKernelRebooter(ContainerBuilder $container)
{
$definition = new Definition(KernelRebooter::class, [new Reference(self::KERNEL_ID)]);
$definition->addTag(EventDispatcherExtension::SUBSCRIBER_TAG);
$container->setDefinition(self::KERNEL_ID . '.rebooter', $definition);
}
/**
* @param ExtensionManager $extensionManager
*/
private function registerSymfonyDriverFactory(ExtensionManager $extensionManager)
{
/** @var MinkExtension $minkExtension */
$minkExtension = $extensionManager->getExtension('mink');
if (null === $minkExtension) {
return;
}
$minkExtension->registerDriverFactory(new SymfonyDriverFactory(
'symfony',
new Reference(self::DRIVER_KERNEL_ID)
));
}
}