Skip to content
This repository has been archived by the owner on Jul 22, 2021. It is now read-only.

Feat: symfony container #1

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ coverage.xml
.temp/coverage.php
*.swp
*.swo

/var
13 changes: 11 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,20 @@
"Pest\\Symfony\\": "src/"
},
"files": [
"src/Autoload.php"
"src/App.php"
]
},
"autoload-dev": {
"psr-4": {
"Pest\\Symfony\\Tests\\App\\": "tests/app",
"Pest\\Symfony\\Tests\\Plugin\\": "tests/plugin"
}
},
"require-dev": {
"pestphp/pest-dev-tools": "dev-master"
"pestphp/pest-dev-tools": "dev-master",
"symfony/framework-bundle": "~5.0",
"symfony/http-kernel": "~5.0",
"symfony/yaml": "~5.0"
bpolaszek marked this conversation as resolved.
Show resolved Hide resolved
},
"extra": {
"branch-alias": {
Expand Down
8 changes: 7 additions & 1 deletion phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
>
<php>
<ini name="error_reporting" value="-1" />
<server name="APP_ENV" value="test" force="true" />
<server name="KERNEL_CLASS" value="Pest\Symfony\Tests\App\Kernel" force="true" />
<server name="SHELL_VERBOSITY" value="-1" />
</php>
<testsuites>
<testsuite name="default">
<directory suffix=".php">./tests</directory>
<directory suffix=".php">./tests/plugin</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
Expand Down
32 changes: 32 additions & 0 deletions src/App.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Pest\Symfony;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Kernel;

function app(bool $reInstanciate = false): Kernel
{
static $kernel;

if (null === $kernel || $reInstanciate) {
$env = $_ENV['APP_ENV'] ?? $_SERVER['APP_ENV'] ?? 'test';
$debug = $_ENV['APP_DEBUG'] ?? $_SERVER['APP_DEBUG'] ?? true;

$kernelClass = Plugin::getKernelClass();
$kernel = new $kernelClass((string) $env, (bool) $debug);
$kernel->boot();
}

return $kernel;
}
bpolaszek marked this conversation as resolved.
Show resolved Hide resolved

function container(?Kernel $app = null): ContainerInterface
{
$app = $app ?? app();
$container = $app->getContainer();

return $container->has('test.service_container') ? $container->get('test.service_container') : $container;
bpolaszek marked this conversation as resolved.
Show resolved Hide resolved
}
18 changes: 0 additions & 18 deletions src/Autoload.php

This file was deleted.

23 changes: 0 additions & 23 deletions src/Example.php

This file was deleted.

27 changes: 26 additions & 1 deletion src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,36 @@

// use Pest\Contracts\Plugins\AddsOutput;
// use Pest\Contracts\Plugins\HandlesArguments;
use InvalidArgumentException;
use Symfony\Component\HttpKernel\Kernel;

/**
* @internal
*/
final class Plugin
{
// ..
private const DEFAULT_KERNEL_CLASS = 'App\\Test';

/**
* @var string
*/
private static $KERNEL_CLASS;

public static function setKernelClass(string $kernelClass): void
{
if (!\is_a($kernelClass, Kernel::class, true)) {
$error = \sprintf('Expected instance of %s, %s given.', Kernel::class, $kernelClass);
throw new InvalidArgumentException($error);
}
self::$KERNEL_CLASS = $kernelClass;
}

public static function getKernelClass(): string
bpolaszek marked this conversation as resolved.
Show resolved Hide resolved
{
if (null === self::$KERNEL_CLASS) {
self::setKernelClass($_SERVER['KERNEL_CLASS'] ?? self::DEFAULT_KERNEL_CLASS);
}

return self::$KERNEL_CLASS;
}
}
3 changes: 0 additions & 3 deletions tests/Example.php

This file was deleted.

5 changes: 0 additions & 5 deletions tests/Functions.php

This file was deleted.

58 changes: 58 additions & 0 deletions tests/app/Kernel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace Pest\Symfony\Tests\App;

use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;

/**
* @codeCoverageIgnore
*/
class Kernel extends BaseKernel
{
use MicroKernelTrait;

public function getProjectDir(): string
{
return __DIR__;
}

public function getCacheDir(): string
{
return \dirname(__DIR__, 2) . '/var/cache';
}

public function getLogDir(): string
{
return \dirname(__DIR__, 2) . '/var/log';
}

protected function configureContainer(ContainerConfigurator $container): void
{
$container->import('./config/{packages}/*.yaml');
$container->import('./config/{packages}/' . $this->environment . '/*.yaml');

if (is_file(\dirname(__DIR__) . '/config/services.yaml')) {
$container->import('./config/{services}.yaml');
$container->import('./config/{services}_' . $this->environment . '.yaml');
} elseif (is_file($path = \dirname(__DIR__) . '/config/services.php')) {
(require $path)($container->withPath($path), $this);
}
}

protected function configureRoutes(RoutingConfigurator $routes): void
{
$routes->import('./config/{routes}/' . $this->environment . '/*.yaml');
$routes->import('./config/{routes}/*.yaml');

if (is_file(\dirname(__DIR__) . '/config/routes.yaml')) {
$routes->import('./config/{routes}.yaml');
} elseif (is_file($path = \dirname(__DIR__) . '/config/routes.php')) {
(require $path)($routes->withPath($path), $this);
}
}
}
23 changes: 23 additions & 0 deletions tests/app/config/bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

use Symfony\Component\Dotenv\Dotenv;

require dirname(__DIR__) . '/vendor/autoload.php';

if (!class_exists(Dotenv::class)) {
throw new LogicException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.');
}

// Load cached env vars if the .env.local.php file exists
// Run "composer dump-env prod" to create it (requires symfony/flex >=1.2)
if (is_array($env = @include dirname(__DIR__) . '/.env.local.php') && (!isset($env['APP_ENV']) || ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? $env['APP_ENV']) === $env['APP_ENV'])) {
(new Dotenv(false))->populate($env);
} else {
// load all the .env files
(new Dotenv(false))->loadEnv(dirname(__DIR__) . '/.env');
}

$_SERVER += $_ENV;
$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev';
$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV'];
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
5 changes: 5 additions & 0 deletions tests/app/config/bundles.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
];
19 changes: 19 additions & 0 deletions tests/app/config/packages/cache.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
framework:
cache:
# Unique name of your app: used to compute stable namespaces for cache keys.
#prefix_seed: your_vendor_name/app_name

# The "app" cache stores to the filesystem by default.
# The data in this cache should persist between deploys.
# Other options include:

# Redis
#app: cache.adapter.redis
#default_redis_provider: redis://localhost

# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
#app: cache.adapter.apcu

# Namespaced pools use the above "app" backend by default
#pools:
#my.dedicated.cache: null
17 changes: 17 additions & 0 deletions tests/app/config/packages/framework.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# see https://symfony.com/doc/current/reference/configuration/framework.html
framework:
secret: '%env(APP_SECRET)%'
#csrf_protection: true
#http_method_override: true

# Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support.
session:
handler_id: null
cookie_secure: auto
cookie_samesite: lax

#esi: true
#fragments: true
php_errors:
log: true
3 changes: 3 additions & 0 deletions tests/app/config/packages/prod/routing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
framework:
router:
strict_requirements: null
3 changes: 3 additions & 0 deletions tests/app/config/packages/routing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
framework:
router:
utf8: true
4 changes: 4 additions & 0 deletions tests/app/config/packages/test/framework.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
framework:
test: true
session:
storage_id: session.storage.mock_file
3 changes: 3 additions & 0 deletions tests/app/config/routes.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#index:
# path: /
# controller: App\Controller\DefaultController::index
3 changes: 3 additions & 0 deletions tests/app/config/routes/dev/framework.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
_errors:
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
prefix: /_error
12 changes: 12 additions & 0 deletions tests/app/config/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:

services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
25 changes: 25 additions & 0 deletions tests/plugin/AppTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Pest\Symfony\Tests\Plugin;

use function Pest\Symfony\app;
use Pest\Symfony\Tests\App\Kernel;
use function PHPUnit\Framework\assertInstanceOf;
use function PHPUnit\Framework\assertNotSame;
use function PHPUnit\Framework\assertSame;

it('instanciates the app', function () {
assertInstanceOf(Kernel::class, app());
});

it('returns a shared instance of the app by default', function () {
$appA = app();
$appB = app();
assertSame($appA, $appB);
});

it('returns a new instance of the app when required', function () {
$appA = app();
$appB = app(true);
assertNotSame($appA, $appB);
});
26 changes: 26 additions & 0 deletions tests/plugin/ContainerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Pest\Symfony\Tests\Plugin;

use function Pest\Symfony\app;
use function Pest\Symfony\container;
use function PHPUnit\Framework\assertInstanceOf;
use function PHPUnit\Framework\assertNotSame;
use function PHPUnit\Framework\assertSame;
use Symfony\Component\DependencyInjection\ContainerInterface;

it('instanciates the container', function () {
assertInstanceOf(ContainerInterface::class, container());
});

it('returns a shared instance of the container by default', function () {
$containerA = container();
$containerB = container();
assertSame($containerA, $containerB);
});

it('returns a new instance of the container when required', function () {
$containerA = container();
$containerB = container(app(true));
assertNotSame($containerA, $containerB);
});