Browse Source

Initial commit

pull/3/head
weather 5 years ago
commit
0661a039ac
  1. 1
      .gitignore
  2. 13
      .php_cs
  3. 31
      Makefile
  4. 31
      README.md
  5. 43
      bin/console
  6. 140
      composer.json
  7. 7171
      composer.lock
  8. 5
      config/bundles.php
  9. 2
      config/packages/cache.yaml
  10. 10
      config/packages/framework.yaml
  11. 3
      config/packages/prod/routing.yaml
  12. 3
      config/packages/routing.yaml
  13. 4
      config/packages/test/framework.yaml
  14. 5
      config/preload.php
  15. 3
      config/routes.yaml
  16. 7
      config/routes/annotations.yaml
  17. 3
      config/routes/dev/framework.yaml
  18. 18
      config/services.yaml
  19. 4
      devops/dist/.env-dist
  20. 8
      devops/docker/.env
  21. 23
      devops/docker/nginx/conf.d/default.conf
  22. 42
      devops/docker/php/Dockerfile
  23. 9
      devops/docker/php/opcache.ini
  24. 11
      devops/docker/php/xdebug.ini
  25. 1
      devops/docker/redis/redis.conf
  26. 15
      devops/scripts/check_compose.sh
  27. 14
      devops/scripts/init.sh
  28. 30
      devops/scripts/install.sh
  29. 54
      docker-compose.yaml
  30. 2
      public/bundles/.gitignore
  31. 22
      public/index.php
  32. 22
      src/Controller/IndexController.php
  33. 38
      src/Kernel.php
  34. 404
      symfony.lock
  35. 0
      tests/_data/.gitignore
  36. 2
      tests/_output/.gitignore
  37. 26
      tests/_support/AcceptanceTester.php
  38. 10
      tests/_support/ApiTester.php
  39. 9
      tests/_support/Helper/Acceptance.php
  40. 9
      tests/_support/Helper/Api.php
  41. 9
      tests/_support/Helper/Unit.php
  42. 61
      tests/_support/UnitTester.php
  43. 2
      tests/_support/_generated/.gitignore
  44. 13
      tests/acceptance.suite.yml
  45. 23
      tests/acceptance/Controller/PageControllerCest.php
  46. 8
      tests/api.suite.yml
  47. 36
      tests/api/Controller/PageControllerCest.php
  48. 16
      tests/codeception.yml
  49. 8
      tests/unit.suite.yml
  50. 33
      tests/unit/KernelTest.php
  51. 2
      var/cache/.gitignore
  52. 2
      var/log/.gitignore
  53. 2
      var/php-cs-fixer/.gitignore
  54. 2
      var/sessions/.gitignore
  55. 2
      vendor/.gitignore

1
.gitignore

@ -0,0 +1 @@
/.env

13
.php_cs

@ -0,0 +1,13 @@
<?php
$finder = PhpCsFixer\Finder::create()
->in(__DIR__)
->exclude('var')
;
return (new PhpCsFixer\Config())->setRules([
'@Symfony' => true,
'array_syntax' => ['syntax' => 'short'],
])
->setFinder($finder)
;

31
Makefile

@ -0,0 +1,31 @@
MAKEFLAGS += --silent
ENV_FILE=devops/docker/.env
include $(ENV_FILE)
export $(shell sed 's/=.*//' $(ENV_FILE))
.PHONY: *
DOCKER_COMPOSE=docker-compose
# Installation
install: stop
./devops/scripts/install.sh
init: start
./devops/scripts/init.sh
clean:
$(DOCKER_COMPOSE) down --rmi local -v
# Serving
start: install
$(DOCKER_COMPOSE) up -d
stop:
$(DOCKER_COMPOSE) down
enter-php:
$(DOCKER_COMPOSE) exec php bash
prepare-request:
$(DOCKER_COMPOSE) exec -T php bash -c "composer run prepare-request"
.DEFAULT_GOAL := init

31
README.md

@ -0,0 +1,31 @@
# symfony-5-cli-template
Template repo "pure-skeleton" with symfony 5.2. Includes:
- local devops via docker-compose and make
- codeception support with acceptance/api/unit-testing
- php/yaml linters
- php/composer code style fixers
### Requirements
- [docker 19+](https://docs.docker.com/engine/install/)
- [docker-compose 1.15+](https://docs.docker.com/compose/install/)
- [make 4.3+](https://www.gnu.org/software/make/)
### Install
```shell script
make init
```
### Development
Enter inside docker container
```shell script
make enter-php
```
Run linters/tests and formatting the code
```shell script
make prepare-request
```
See other useful commands in **Makefile** and **composer.json** under *scripts*

43
bin/console

@ -0,0 +1,43 @@
#!/usr/bin/env php
<?php
use App\Kernel;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\ErrorHandler\Debug;
if (!in_array(PHP_SAPI, ['cli', 'phpdbg', 'embed'], true)) {
echo 'Warning: The console should be invoked via the CLI version of PHP, not the '.PHP_SAPI.' SAPI'.PHP_EOL;
}
set_time_limit(0);
require dirname(__DIR__).'/vendor/autoload.php';
if (!class_exists(Application::class) || !class_exists(Dotenv::class)) {
throw new LogicException('You need to add "symfony/framework-bundle" and "symfony/dotenv" as Composer dependencies.');
}
$input = new ArgvInput();
if (null !== $env = $input->getParameterOption(['--env', '-e'], null, true)) {
putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env);
}
if ($input->hasParameterOption('--no-debug', true)) {
putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0');
}
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
if ($_SERVER['APP_DEBUG']) {
umask(0000);
if (class_exists(Debug::class)) {
Debug::enable();
}
}
$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$application = new Application($kernel);
$application->run($input);

140
composer.json

@ -0,0 +1,140 @@
{
"type": "project",
"license": "MIT",
"require": {
"php": "7.4.*",
"ext-apcu": "5.1.*",
"ext-ctype": "7.4.*",
"ext-iconv": "7.4.*",
"symfony/console": "5.2.*",
"symfony/dotenv": "5.2.*",
"symfony/flex": "^1.3.1",
"symfony/framework-bundle": "5.2.*",
"symfony/yaml": "5.2.*"
},
"replace": {
"symfony/polyfill-ctype": "*",
"symfony/polyfill-iconv": "*",
"symfony/polyfill-php72": "*"
},
"require-dev": {
"codeception/codeception": "^4.1",
"codeception/module-asserts": "^1.3",
"codeception/module-phpbrowser": "^1.0",
"codeception/module-rest": "^1.2",
"ergebnis/composer-normalize": "^2.13",
"friendsofphp/php-cs-fixer": "^2.18",
"php-parallel-lint/php-parallel-lint": "^1.2",
"roave/security-advisories": "dev-master"
},
"config": {
"apcu-autoloader": true,
"cache-files-ttl": 7776000,
"discard-changes": true,
"optimize-autoloader": true,
"preferred-install": {
"*": "dist"
},
"sort-packages": true
},
"extra": {
"composer-normalize": {
"indent-size": 4,
"indent-style": "space"
},
"symfony": {
"allow-contrib": false,
"require": "5.2.*"
}
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/",
"App\\Tests\\Helper\\": "tests/_support/Helper",
"App\\Tests\\_generated\\": "tests/_support/_generated"
}
},
"minimum-stability": "stable",
"prefer-stable": true,
"scripts": {
"post-install-cmd": [
"@auto-scripts"
],
"post-update-cmd": [
"@auto-scripts"
],
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd"
},
"codecept": "codecept -c tests/codeception.yml",
"json-cs-fix": "composer normalize",
"lint:php": [
"parallel-lint --no-progress --no-colors --blame ./bin/console",
"parallel-lint --no-progress --no-colors --blame ./config/bundles.php",
"parallel-lint --no-progress --no-colors --blame ./config/preload.php",
"parallel-lint --no-progress --no-colors --blame ./public/index.php",
"parallel-lint --no-progress --no-colors --blame ./src",
"parallel-lint --no-progress --no-colors --blame ./tests/_support/Helper",
"parallel-lint --no-progress --no-colors --blame ./tests/_support/AcceptanceTester.php",
"parallel-lint --no-progress --no-colors --blame ./tests/_support/ApiTester.php",
"parallel-lint --no-progress --no-colors --blame ./tests/_support/UnitTester.php",
"parallel-lint --no-progress --no-colors --blame ./tests/acceptance",
"parallel-lint --no-progress --no-colors --blame ./tests/api",
"parallel-lint --no-progress --no-colors --blame ./tests/unit",
"parallel-lint --no-progress --no-colors --blame ./.php_cs"
],
"lint:yaml": [
"bin/console --quiet --no-debug l:yaml ./config/packages",
"bin/console --quiet --no-debug l:yaml ./config/routes",
"bin/console --quiet --no-debug l:yaml ./config/routes.yaml",
"bin/console --quiet --no-debug l:yaml ./config/services.yaml",
"bin/console --quiet --no-debug l:yaml ./tests/acceptance.suite.yml",
"bin/console --quiet --no-debug l:yaml ./tests/api.suite.yml",
"bin/console --quiet --no-debug l:yaml ./tests/codeception.yml",
"bin/console --quiet --no-debug l:yaml ./tests/unit.suite.yml"
],
"php-cs-fix": [
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache bin/console",
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache config/bundles.php",
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache config/preload.php",
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache public/index.php",
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache src",
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache tests/_support/Helper",
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache tests/_support/AcceptanceTester.php",
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache tests/_support/ApiTester.php",
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache tests/_support/UnitTester.php",
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache tests/acceptance",
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache tests/api",
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache tests/unit",
"php vendor/bin/php-cs-fixer fix --cache-file=var/php-cs-fixer/.php-cs.cache .php_cs"
],
"prepare-request": [
"@json-cs-fix",
"@lint:yaml",
"@lint:php",
"@lint:container",
"@php-cs-fix",
"@test:unit",
"@test:api",
"@test:acceptance"
],
"test:acceptance": [
"@codecept build -q",
"@codecept run acceptance"
],
"test:api": [
"@codecept build -q",
"@codecept run api"
],
"test:unit": [
"@codecept build -q",
"@codecept run unit --no-rebuild --coverage-html --coverage-text --no-colors"
]
}
}

7171
composer.lock
File diff suppressed because it is too large
View File

5
config/bundles.php

@ -0,0 +1,5 @@
<?php
return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
];

2
config/packages/cache.yaml

@ -0,0 +1,2 @@
framework:
cache:

10
config/packages/framework.yaml

@ -0,0 +1,10 @@
framework:
secret: '%env(APP_SECRET)%'
session:
handler_id: null
cookie_secure: auto
cookie_samesite: lax
php_errors:
log: true

3
config/packages/prod/routing.yaml

@ -0,0 +1,3 @@
framework:
router:
strict_requirements: null

3
config/packages/routing.yaml

@ -0,0 +1,3 @@
framework:
router:
utf8: true

4
config/packages/test/framework.yaml

@ -0,0 +1,4 @@
framework:
test: true
session:
storage_id: session.storage.mock_file

5
config/preload.php

@ -0,0 +1,5 @@
<?php
if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
}

3
config/routes.yaml

@ -0,0 +1,3 @@
#index:
# path: /
# controller: App\Controller\DefaultController::index

7
config/routes/annotations.yaml

@ -0,0 +1,7 @@
controllers:
resource: ../../src/Controller/
type: annotation
kernel:
resource: ../../src/Kernel.php
type: annotation

3
config/routes/dev/framework.yaml

@ -0,0 +1,3 @@
_errors:
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
prefix: /_error

18
config/services.yaml

@ -0,0 +1,18 @@
parameters:
services:
_defaults:
autowire: true
autoconfigure: true
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
- '../src/Tests/'
App\Controller\:
resource: '../src/Controller/'
tags: ['controller.service_arguments']

4
devops/dist/.env-dist

@ -0,0 +1,4 @@
APP_ENV=dev
APP_SECRET=a1def1573d162b7d97ed994df9d37949
DATABASE_URL=mysql://root:rootroot@127.0.0.1:3001/template?serverVersion=5.7

8
devops/docker/.env

@ -0,0 +1,8 @@
COMPOSE_PROJECT_NAME=template
PROJECT_ID=001
COMPOSE_DOCKER_CLI_BUILD=1
DOCKER_BUILDKIT=1
MYSQL_USER=root
MYSQL_PASSWORD=rootroot

23
devops/docker/nginx/conf.d/default.conf

@ -0,0 +1,23 @@
server {
set $projectLocation /var/www/localhost/htdocs/current;
server_name localhost;
client_max_body_size 10M;
client_body_buffer_size 1024k;
location / {
root $projectLocation/public;
error_log /var/log/nginx/localhost-error.log;
access_log /var/log/nginx/localhost-access.log;
location ~ ^/(.*)$ {
try_files $uri /index.php =404;
fastcgi_pass php:9000;
include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
}
}

42
devops/docker/php/Dockerfile

@ -0,0 +1,42 @@
FROM php:7.4-fpm
# user mapping
ARG HOME
ARG USER
ARG UID
ARG GID
# zip
RUN apt-get update && apt-get install -y \
libzip-dev \
zlib1g-dev
RUN docker-php-ext-install zip
RUN apt-get install -y git
RUN docker-php-ext-install \
pcntl \
mysqli \
pdo_mysql
# APCU
RUN pecl install apcu-5.1.17 && docker-php-ext-enable apcu
# opcache
RUN docker-php-ext-install opcache
COPY opcache.ini /usr/local/etc/php/conf.d/opcache.ini
# xdebug
RUN pecl install xdebug-2.9.5 && docker-php-ext-enable xdebug
COPY xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini
RUN groupadd --gid ${GID} ${USER} \
&& useradd --uid ${UID} --gid ${GID} --shell /bin/bash --home-dir ${HOME} ${USER}
# composer
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php composer-setup.php --version=2.0.9 --install-dir=/usr/local/bin --filename=composer
USER ${USER}
WORKDIR /var/www/localhost/htdocs/current

9
devops/docker/php/opcache.ini

@ -0,0 +1,9 @@
[opcache]
opcache.enable=1
opcache.revalidate_freq=0
opcache.validate_timestamps=1
opcache.max_accelerated_files=10000
opcache.memory_consumption=192
opcache.max_wasted_percentage=10
opcache.interned_strings_buffer=16
opcache.fast_shutdown=1

11
devops/docker/php/xdebug.ini

@ -0,0 +1,11 @@
xdebug.remote_host=172.17.0.1
xdebug.default_enable=1
xdebug.remote_autostart=1
xdebug.remote_connect_back=0
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_port=9000
xdebug.extended_info = 1
xdebug.idekey="PHPSTORM"
xdebug.max_nesting_level=1000

1
devops/docker/redis/redis.conf

@ -0,0 +1 @@
bind 0.0.0.0

15
devops/scripts/check_compose.sh

@ -0,0 +1,15 @@
#!/usr/bin/env sh
if ! [ -x "$(command -v docker-compose)" ]; then
echo 'Error: docker-compose is not installed.' >&2
exit 1
fi
DOCKER_COMPOSE_VERSION=$(docker-compose version --short)
DOCKER_COMPOSE_MIN_VERSION="1.25.0"
# shellcheck disable=SC2039
if [ "$DOCKER_COMPOSE_VERSION" \< "$DOCKER_COMPOSE_MIN_VERSION" ]; then
echo "Update docker-compose. Required version $DOCKER_COMPOSE_MIN_VERSION and higher" >&2
exit 2
fi

14
devops/scripts/init.sh

@ -0,0 +1,14 @@
#!/usr/bin/env sh
# shellcheck disable=SC2046
SCRIPTS_DIRECTORY=$(dirname $(realpath "$0"))
set -e
"$SCRIPTS_DIRECTORY"/check_compose.sh
docker-compose exec -T php bash -c "chmod -R 777 var/cache/"
docker-compose exec -T php bash -c "chmod -R 777 var/log/"
docker-compose exec -T php bash -c "chmod -R 777 var/sessions/"
docker-compose exec -T php bash -c "composer install"

30
devops/scripts/install.sh

@ -0,0 +1,30 @@
#!/usr/bin/env sh
if ! [ -x "$(command -v docker-compose)" ]; then
echo 'Error: docker-compose is not installed.' >&2
exit 1
fi
set -e
set -a
[ -f devops/docker/.env ] && . devops/docker/.env
set +a
# shellcheck disable=SC2028
echo "### Building containers ..."
docker-compose build \
--build-arg HOME=$HOME \
--build-arg USER=$USER \
--build-arg UID=$(id -u) \
--build-arg GID=$(id -g)
# shellcheck disable=SC2028
echo "### Creating .env ..."
ENV_FILE=.env
if [ ! -f "$ENV_FILE" ]; then
cp devops/dist/.env-dist "$ENV_FILE"
echo "Successfully created"
else
echo ".env file already exists"
fi

54
docker-compose.yaml

@ -0,0 +1,54 @@
version: "3"
services:
mysql:
image: mysql:5.7
restart: on-failure
environment:
MYSQL_USER: ${MYSQL_USER}
MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_DATABASE: ${COMPOSE_PROJECT_NAME}
ports:
- "3$PROJECT_ID:3306"
redis:
image: redis:6.0.10-alpine
volumes:
- ./devops/docker/redis/redis.conf:/redis.conf
command: [ "redis-server", "/redis.conf" ]
ports:
- "6$PROJECT_ID:6379"
php:
build:
context: devops/docker/php
args:
HOME: "$HOME"
USER: "$USER"
UID: "$UID"
GID: "$GID"
restart: unless-stopped
depends_on:
- mysql
- redis
environment:
- COMPOSER_MEMORY_LIMIT=-1
- PHP_IDE_CONFIG=serverName=${COMPOSE_PROJECT_NAME}
- PROJECT_PORT="8$PROJECT_ID"
volumes:
- ./:/var/www/localhost/htdocs/current
- ${HOME}/.composer:${HOME}/.composer
- ${HOME}/.ssh:${HOME}/.ssh
expose:
- "9000"
nginx:
image: nginx:1.19
restart: unless-stopped
depends_on:
- php
volumes:
- ./:/var/www/localhost/htdocs/current
- ./devops/docker/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
ports:
- "8$PROJECT_ID:80"

2
public/bundles/.gitignore

@ -0,0 +1,2 @@
*
!.gitignore

22
public/index.php

@ -0,0 +1,22 @@
<?php
use App\Kernel;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\ErrorHandler\Debug;
use Symfony\Component\HttpFoundation\Request;
require dirname(__DIR__).'/vendor/autoload.php';
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
if ($_SERVER['APP_DEBUG']) {
umask(0000);
Debug::enable();
}
$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

22
src/Controller/IndexController.php

@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
class IndexController
{
/**
* @Route("/", name="index.any")
*/
public function index(): JsonResponse
{
return new JsonResponse(
JsonResponse::$statusTexts[JsonResponse::HTTP_BAD_REQUEST],
JsonResponse::HTTP_BAD_REQUEST
);
}
}

38
src/Kernel.php

@ -0,0 +1,38 @@
<?php
namespace 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;
class Kernel extends BaseKernel
{
use MicroKernelTrait;
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);
}
}
}

404
symfony.lock

@ -0,0 +1,404 @@
{
"behat/gherkin": {
"version": "v4.7.1"
},
"codeception/codeception": {
"version": "2.3",
"recipe": {
"repo": "github.com/symfony/recipes-contrib",
"branch": "master",
"version": "2.3",
"ref": "5d3fec49d4a7ecb411c417fc51cf48b06a86946d"
},
"files": [
"codeception.yml",
"tests/_data/.gitignore",
"tests/_output/.gitignore",
"tests/_support/AcceptanceTester.php",
"tests/_support/FunctionalTester.php",
"tests/_support/Helper/Acceptance.php",
"tests/_support/Helper/Functional.php",
"tests/_support/Helper/Unit.php",
"tests/_support/UnitTester.php",
"tests/_support/_generated/.gitignore",
"tests/acceptance/.gitignore",
"tests/functional/.gitignore",
"tests/unit/.gitignore",
"tests/acceptance.suite.yml",
"tests/functional.suite.yml",
"tests/unit.suite.yml"
]
},
"codeception/lib-asserts": {
"version": "1.13.2"
},
"codeception/lib-innerbrowser": {
"version": "1.3.6"
},
"codeception/module-asserts": {
"version": "1.3.1"
},
"codeception/module-phpbrowser": {
"version": "1.0.2"
},
"codeception/module-rest": {
"version": "1.2.7"
},
"codeception/phpunit-wrapper": {
"version": "9.0.6"
},
"codeception/stub": {
"version": "3.7.0"
},
"composer/semver": {
"version": "3.2.4"
},
"composer/xdebug-handler": {
"version": "1.4.5"
},
"doctrine/annotations": {
"version": "1.0",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "1.0",
"ref": "a2759dd6123694c8d901d0ec80006e044c2e6457"
},
"files": [
"config/routes/annotations.yaml"
]
},
"doctrine/instantiator": {
"version": "1.4.0"
},
"doctrine/lexer": {
"version": "1.2.1"
},
"ergebnis/composer-normalize": {
"version": "2.13.2"
},
"ergebnis/json-normalizer": {
"version": "1.0.2"
},
"ergebnis/json-printer": {
"version": "3.1.1"
},
"friendsofphp/php-cs-fixer": {
"version": "2.16",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "2.16",
"ref": "c1947bad147704aeaf0285745f0baae927a58959"
},
"files": [
".php_cs.dist"
]
},
"guzzlehttp/guzzle": {
"version": "7.2.0"
},
"guzzlehttp/promises": {
"version": "1.4.0"
},
"guzzlehttp/psr7": {
"version": "1.7.0"
},
"justinrainbow/json-schema": {
"version": "5.2.10"
},
"localheinz/diff": {
"version": "1.1.1"
},
"myclabs/deep-copy": {
"version": "1.10.2"
},
"nikic/php-parser": {
"version": "v4.10.4"
},
"phar-io/manifest": {
"version": "2.0.1"
},
"phar-io/version": {
"version": "3.0.4"
},
"php-cs-fixer/diff": {
"version": "v1.3.1"
},
"php-parallel-lint/php-parallel-lint": {
"version": "v1.2.0"
},
"phpdocumentor/reflection-common": {
"version": "2.2.0"
},
"phpdocumentor/reflection-docblock": {
"version": "5.2.2"
},
"phpdocumentor/type-resolver": {
"version": "1.4.0"
},
"phpspec/prophecy": {
"version": "1.12.2"
},
"phpunit/php-code-coverage": {
"version": "9.2.5"
},
"phpunit/php-file-iterator": {
"version": "3.0.5"
},
"phpunit/php-invoker": {
"version": "3.1.1"
},
"phpunit/php-text-template": {
"version": "2.0.4"
},
"phpunit/php-timer": {
"version": "5.0.3"
},
"phpunit/phpunit": {
"version": "4.7",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "4.7",
"ref": "477e1387616f39505ba79715f43f124836020d71"
},
"files": [
".env.test",
"phpunit.xml.dist",
"tests/bootstrap.php"
]
},
"psr/cache": {
"version": "1.0.1"
},
"psr/container": {
"version": "1.0.0"
},
"psr/event-dispatcher": {
"version": "1.0.0"
},
"psr/http-client": {
"version": "1.0.1"
},
"psr/http-message": {
"version": "1.0.1"
},
"psr/log": {
"version": "1.1.3"
},
"ralouphie/getallheaders": {
"version": "3.0.3"
},
"roave/security-advisories": {
"version": "dev-master"
},
"sebastian/cli-parser": {
"version": "1.0.1"
},
"sebastian/code-unit": {
"version": "1.0.8"
},
"sebastian/code-unit-reverse-lookup": {
"version": "2.0.3"
},
"sebastian/comparator": {
"version": "4.0.6"
},
"sebastian/complexity": {
"version": "2.0.2"
},
"sebastian/diff": {
"version": "4.0.4"
},
"sebastian/environment": {
"version": "5.1.3"
},
"sebastian/exporter": {
"version": "4.0.3"
},
"sebastian/global-state": {
"version": "5.0.2"
},
"sebastian/lines-of-code": {
"version": "1.0.3"
},
"sebastian/object-enumerator": {
"version": "4.0.4"
},
"sebastian/object-reflector": {
"version": "2.0.4"
},
"sebastian/recursion-context": {
"version": "4.0.4"
},
"sebastian/resource-operations": {
"version": "3.0.3"
},
"sebastian/type": {
"version": "2.3.1"
},
"sebastian/version": {
"version": "3.0.2"
},
"softcreatr/jsonpath": {
"version": "0.7.2"
},
"symfony/browser-kit": {
"version": "v5.2.2"
},
"symfony/cache": {
"version": "v5.2.2"
},
"symfony/cache-contracts": {
"version": "v2.2.0"
},
"symfony/config": {
"version": "v5.2.2"
},
"symfony/console": {
"version": "5.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "5.1",
"ref": "c6d02bdfba9da13c22157520e32a602dbee8a75c"
},
"files": [
"bin/console"
]
},
"symfony/css-selector": {
"version": "v5.2.2"
},
"symfony/dependency-injection": {
"version": "v5.2.2"
},
"symfony/deprecation-contracts": {
"version": "v2.2.0"
},
"symfony/dom-crawler": {
"version": "v5.2.2"
},
"symfony/dotenv": {
"version": "v5.2.2"
},
"symfony/error-handler": {
"version": "v5.2.2"
},
"symfony/event-dispatcher": {
"version": "v5.2.2"
},
"symfony/event-dispatcher-contracts": {
"version": "v2.2.0"
},
"symfony/filesystem": {
"version": "v5.2.2"
},
"symfony/finder": {
"version": "v5.2.2"
},
"symfony/flex": {
"version": "1.0",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "1.0",
"ref": "c0eeb50665f0f77226616b6038a9b06c03752d8e"
},
"files": [
".env"
]
},
"symfony/framework-bundle": {
"version": "5.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "5.2",
"ref": "6ec87563dcc85cd0c48856dcfbfc29610506d250"
},
"files": [
"config/packages/cache.yaml",
"config/packages/framework.yaml",
"config/packages/test/framework.yaml",
"config/preload.php",
"config/routes/dev/framework.yaml",
"config/services.yaml",
"public/index.php",
"src/Controller/.gitignore",
"src/Kernel.php"
]
},
"symfony/http-client-contracts": {
"version": "v2.3.1"
},
"symfony/http-foundation": {
"version": "v5.2.2"
},
"symfony/http-kernel": {
"version": "v5.2.2"
},
"symfony/options-resolver": {
"version": "v5.2.2"
},
"symfony/polyfill-intl-grapheme": {
"version": "v1.22.0"
},
"symfony/polyfill-intl-normalizer": {
"version": "v1.22.0"
},
"symfony/polyfill-mbstring": {
"version": "v1.22.0"
},
"symfony/polyfill-php70": {
"version": "v1.20.0"
},
"symfony/polyfill-php73": {
"version": "v1.22.0"
},
"symfony/polyfill-php80": {
"version": "v1.22.0"
},
"symfony/process": {
"version": "v5.2.2"
},
"symfony/routing": {
"version": "5.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "5.1",
"ref": "b4f3e7c95e38b606eef467e8a42a8408fc460c43"
},
"files": [
"config/packages/prod/routing.yaml",
"config/packages/routing.yaml",
"config/routes.yaml"
]
},
"symfony/service-contracts": {
"version": "v2.2.0"
},
"symfony/stopwatch": {
"version": "v5.2.2"
},
"symfony/string": {
"version": "v5.2.2"
},
"symfony/var-dumper": {
"version": "v5.2.2"
},
"symfony/var-exporter": {
"version": "v5.2.2"
},
"symfony/yaml": {
"version": "v5.2.2"
},
"theseer/tokenizer": {
"version": "1.2.0"
},
"webmozart/assert": {
"version": "1.9.1"
}
}

0
tests/_data/.gitignore

2
tests/_output/.gitignore

@ -0,0 +1,2 @@
*
!.gitignore

26
tests/_support/AcceptanceTester.php

@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace App\Tests;
/**
* Inherited Methods.
*
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
*
* @SuppressWarnings(PHPMD)
*/
class AcceptanceTester extends \Codeception\Actor
{
use _generated\AcceptanceTesterActions;
}

10
tests/_support/ApiTester.php

@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace App\Tests;
class ApiTester extends \Codeception\Actor
{
use _generated\ApiTesterActions;
}

9
tests/_support/Helper/Acceptance.php

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace App\Tests\Helper;
class Acceptance extends \Codeception\Module
{
}

9
tests/_support/Helper/Api.php

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace App\Tests\Helper;
class Api extends \Codeception\Module
{
}

9
tests/_support/Helper/Unit.php

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace App\Tests\Helper;
class Unit extends \Codeception\Module
{
}

61
tests/_support/UnitTester.php

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace App\Tests;
use ReflectionClass;
use ReflectionException;
use ReflectionProperty;
/**
* Inherited Methods.
*
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
*
* @SuppressWarnings(PHPMD)
*/
class UnitTester extends \Codeception\Actor
{
use _generated\UnitTesterActions;
/**
* @param mixed $classObject
*
* @throws ReflectionException
*/
public function getClassProperty($classObject, string $propertyName): ReflectionProperty
{
$reflector = new ReflectionClass($classObject);
$property = $reflector->getProperty($propertyName);
$property->setAccessible(true);
return $property;
}
/**
* @param mixed $object
*
* @return mixed
*
* @throws ReflectionException
*/
public function invokeMethod($object, string $methodName, array $parameters = [])
{
$reflection = new ReflectionClass(get_class($object));
$method = $reflection->getMethod($methodName);
$method->setAccessible(true);
return $method->invokeArgs($object, $parameters);
}
}

2
tests/_support/_generated/.gitignore

@ -0,0 +1,2 @@
*
!.gitignore

13
tests/acceptance.suite.yml

@ -0,0 +1,13 @@
actor: AcceptanceTester
modules:
enabled:
- \App\Tests\Helper\Acceptance
- PhpBrowser
config:
PhpBrowser:
url: http://nginx/
proxy: ''
curl:
CURLOPT_TIMEOUT: 10

23
tests/acceptance/Controller/PageControllerCest.php

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\Tests\acceptance\Controller;
use App\Tests\AcceptanceTester;
class PageControllerCest
{
private AcceptanceTester $tester;
public function _before(AcceptanceTester $tester): void
{
$this->tester = $tester;
}
public function testBaseAvailability(): void
{
$this->tester->amOnPage('/');
$this->tester->seeResponseCodeIs(400);
}
}

8
tests/api.suite.yml

@ -0,0 +1,8 @@
actor: ApiTester
modules:
enabled:
- REST:
url: http://nginx/
depends: PhpBrowser
part: Json
- \App\Tests\Helper\Api

36
tests/api/Controller/PageControllerCest.php

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace App\Tests\api\Controller;
use App\Tests\ApiTester;
use Codeception\Example;
use Iterator;
class PageControllerCest
{
private ApiTester $tester;
public function _before(ApiTester $tester): void
{
$this->tester = $tester;
}
/**
* @dataProvider dataTestBaseAvailability
*/
public function testBaseAvailability(Example $example): void
{
$this->tester->sendGet($example['url']);
$this->tester->seeResponseCodeIs(400);
$this->tester->seeResponseIsJson();
}
protected static function dataTestBaseAvailability(): Iterator
{
yield [
'url' => '/',
];
}
}

16
tests/codeception.yml

@ -0,0 +1,16 @@
namespace: App\Tests
actor_suffix: Tester
paths:
tests: .
output: _output
data: _data
support: _support
coverage:
enabled: true
include:
- ../src/*
exclude:
- ../var/cache/*
extensions:
enabled:
- Codeception\Extension\RunFailed

8
tests/unit.suite.yml

@ -0,0 +1,8 @@
actor: UnitTester
report_useless_tests: true
disallow_test_output: false
shuffle: true
modules:
enabled:
- Asserts
- \App\Tests\Helper\Unit

33
tests/unit/KernelTest.php

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace App\Tests\unit;
use App\Kernel;
use App\Tests\UnitTester;
use Codeception\Test\Unit;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
/**
* @internal
*/
class KernelTest extends Unit
{
protected UnitTester $tester;
/**
* @test
*/
public function isExtends(): void
{
/** @var Kernel|MockObject $kernel */
$kernel = $this->getMockBuilder(Kernel::class)
->disableOriginalConstructor()
->getMock()
;
self::assertTrue(is_subclass_of($kernel, BaseKernel::class));
}
}

2
var/cache/.gitignore

@ -0,0 +1,2 @@
*
!.gitignore

2
var/log/.gitignore

@ -0,0 +1,2 @@
*
!.gitignore

2
var/php-cs-fixer/.gitignore

@ -0,0 +1,2 @@
*
!.gitignore

2
var/sessions/.gitignore

@ -0,0 +1,2 @@
*
!.gitignore

2
vendor/.gitignore

@ -0,0 +1,2 @@
*
!.gitignore