├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── bin
├── phpunit
└── symfony-grumphp
├── composer.json
├── src
├── Command
│ ├── AbstractCommand.php
│ ├── InstallCommand.php
│ └── UninstallCommand.php
└── dist
│ ├── .php_cs
│ ├── grumphp.yml
│ ├── phpstan.neon
│ └── phpunit.xml.dist
└── tests
├── Command
├── InstallCommandTest.php
└── UninstallCommandTest.php
└── bootstrap.php
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 | composer.lock
3 | .idea
4 | .php_cs.cache
5 | grumphp.yml
6 | grumphp.yml.scbak
7 | php_cs.php
8 | php_cs.php.scbak
9 | phpstan.neon
10 | phpstan.neon.scbak
11 | phpunit.xml.dist
12 | phpunit.xml.dist.scbak
13 | config/cli-config.php
14 | coverage.sh
15 | !src/dist/coverage.sh
16 | build/logs/clover.xml
17 | bin/.phpunit
18 | build/*
19 | .phpunit.cache
20 | .php_cs
21 | *.scbak
22 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - 7.3
4 | - 7.4
5 | - 8.0
6 |
7 | env:
8 | matrix:
9 | -
10 | cache:
11 | directories:
12 | - "$HOME/.composer/cache"
13 |
14 | before_install:
15 | - alias composer=composer\ --no-interaction && composer selfupdate
16 |
17 | install:
18 | - travis_retry composer update --no-progress --profile --no-scripts --no-suggest && composer install
19 |
20 | script:
21 | - bin/symfony-grumphp install -q
22 | - vendor/bin/grumphp run --testsuite=no-coverage
23 | - bin/symfony-grumphp install -q
24 | - bin/symfony-grumphp uninstall -q
25 |
26 | after_success:
27 | - bin/symfony-grumphp install -q
28 | - vendor/bin/php-coveralls -v
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Marcin Harasim
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Symfony + GrumPHP
2 |
3 | `symfony-grumphp` is configured GrumPHP with bunch of tools for static code analysis mainly based on [PSRs](https://www.php-fig.org/psr/) and [Symfony Coding Standards](https://symfony.com/doc/current/contributing/code/standards.html) for Symfony Framework projects.
4 |
5 | [](https://github.com/sci3ma/symfony-grumphp)
6 | [](https://github.com/sci3ma/symfony-grumphp/blob/master/LICENSE)
7 | [](https://packagist.org/packages/sci3ma/symfony-grumphp/stats)
8 | [](https://github.com/sci3ma/symfony-grumphp/commits/master)
9 | [](https://travis-ci.com/sci3ma/symfony-grumphp)
10 | [](https://coveralls.io/github/sci3ma/symfony-grumphp)
11 |
12 | ## Included tools
13 | * [GrumPHP](https://github.com/phpro/grumphp): `phpro/grumphp`
14 | * [PhpCpd](https://github.com/sebastianbergmann/phpcpd): `sebastian/phpcpd`
15 | * [PHP-CS-FIXER](https://github.com/FriendsOfPHP/PHP-CS-Fixer): `friendsofphp/php-cs-fixer`
16 | * [PHPLint](https://github.com/php-parallel-lint/PHP-Parallel-Lint): `php-parallel-lint/php-parallel-lint`
17 | * [PhpMd](https://github.com/phpmd/phpmd): `phpmd/phpmd`
18 | * [PHPStan](https://github.com/phpstan/phpstan): `phpstan/phpstan`
19 | * [Doctrine extension](https://github.com/phpstan/phpstan-doctrine): `phpstan/phpstan-doctrine`
20 | * [PHPUnit extension](https://github.com/phpstan/phpstan-phpunit): `phpstan/phpstan-phpunit`
21 | * [Symfony Framework extension](https://github.com/phpstan/phpstan-symfony): `phpstan/phpstan-symfony`
22 | * [TheCodingMachine's additional rules](https://github.com/thecodingmachine/phpstan-strict-rules): `thecodingmachine/phpstan-strict-rules`
23 | * [PHPUnit Bridge](https://github.com/symfony/phpunit-bridge): `symfony/phpunit-bridge`
24 | * With Clover Coverage and percentage code coverage check
25 | * [Enlightn Security Checker](https://github.com/enlightn/security-checker): `enlightn/security-checker`
26 |
27 | ## Requirements
28 | PHP needs to be a minimum version of PHP 7.3.
29 | Symfony Framework needs to be a minimum version of Symfony Framework 4.0 or 5.0.
30 |
31 | ## Installation
32 | To install `symfony-grumphp`, [install Composer](https://getcomposer.org/download/), execute the following command:
33 | ```
34 | composer require --dev sci3ma/symfony-grumphp
35 | ```
36 | and create (or update) configuration files:
37 | ```
38 | ./vendor/bin/symfony-grumphp install
39 | ```
40 |
41 | ## Configuration
42 | You can, and perhaps you should, check and customize all configured tasks in `grumphp.yml` file in project root folder.
43 |
44 | GrumPHP should be enabled by default but you can also enable GrumPHP yourself:
45 | ```
46 | ./vendor/bin/grumphp git:init
47 | ```
48 | or disable GrumPHP:
49 | ```
50 | ./vendor/bin/grumphp git:deinit
51 | ```
52 | You can find more GrumPHP configuration [here](https://github.com/phpro/grumphp/blob/master/doc/commands.md#installation).
53 |
54 | ##### Test code with the database
55 | If you need to test code that interact with the database you need to instal [`dama/doctrine-test-bundle`](https://github.com/dmaicher/doctrine-test-bundle):
56 | ```
57 | composer require --dev dama/doctrine-test-bundle
58 | ```
59 | and uncomment extension `` in `phpunit.xml.dist`.
60 | Read more about [how to Test Code that Interacts with the Database](https://symfony.com/doc/current/testing/database.html)
61 |
62 | ## Uninstall
63 | If you want to uninstall this library remove configuration files first:
64 | ```
65 | ./vendor/bin/symfony-grumphp uninstall
66 | ```
67 | then remove package:
68 | ```
69 | composer remove sci3ma/symfony-grumphp
70 | ```
71 |
72 | ## Force run
73 | You can run tests/checks our code without commit manually:
74 | ```
75 | ./vendor/bin/grumphp run
76 | ```
77 |
78 |
--------------------------------------------------------------------------------
/bin/phpunit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | add(new InstallCommand());
35 | $application->add(new UninstallCommand());
36 |
37 | try {
38 | $application->run();
39 | } catch (\Exception $exception) {
40 | fwrite(STDERR, $exception->getMessage() . PHP_EOL);
41 | exit(1);
42 | }
43 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sci3ma/symfony-grumphp",
3 | "description": "Configured GrumPHP with bunch of tools for static code analysis Symfony Framework",
4 | "keywords": ["php", "symfony", "grumphp", "phpcs", "phpmd", "phpstan", "phpunit", "code quality", "standards"],
5 | "license": "MIT",
6 | "authors": [
7 | {
8 | "name": "Marcin Harasim",
9 | "email": "marcin.harasim@gmail.com"
10 | }
11 | ],
12 | "type": "library",
13 | "require": {
14 | "php": "^7.3|^8.0",
15 | "composer/composer": "^2.0",
16 | "enlightn/security-checker": "^1.5",
17 | "friendsofphp/php-cs-fixer": "^2.18",
18 | "php-parallel-lint/php-parallel-lint": "^1.2",
19 | "phpmd/phpmd": "^2.9",
20 | "phpro/grumphp": "^1.3",
21 | "phpstan/phpstan": "^0.11.2|^0.12.26",
22 | "phpstan/phpstan-doctrine": "^0.11.1|^0.12.0",
23 | "phpstan/phpstan-phpunit": "^0.11.0|^0.12.0",
24 | "phpstan/phpstan-symfony": "^0.11.1|^0.12.0",
25 | "psr/event-dispatcher": "^1.0",
26 | "sebastian/phpcpd": "^6.0",
27 | "symfony/console": "^4.0|^5.0",
28 | "symfony/filesystem": "^4.0|^5.0",
29 | "symfony/phpunit-bridge": "^4.0|^5.0",
30 | "thecodingmachine/phpstan-strict-rules": "^0.11.2|^0.12.0"
31 | },
32 | "require-dev": {
33 | "php-coveralls/php-coveralls": "^2.4"
34 | },
35 | "autoload": {
36 | "psr-4": {
37 | "MH\\SymfonyGrumPHP\\": "src/",
38 | "MH\\SymfonyGrumPHP\\Tests\\": "tests/"
39 | }
40 | },
41 | "support": {
42 | "issues": "https://github.com/sci3ma/symfony-grumphp/issues"
43 | },
44 | "homepage": "https://github.com/sci3ma/symfony-grumphp",
45 | "config": {
46 | "sort-packages": true
47 | },
48 | "bin": ["bin/symfony-grumphp"]
49 | }
50 |
--------------------------------------------------------------------------------
/src/Command/AbstractCommand.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | abstract class AbstractCommand extends Command
13 | {
14 | /**
15 | * @const array CONF_FILES
16 | */
17 | protected const CONF_FILES = [
18 | 'grumphp.yml',
19 | '.php_cs',
20 | 'phpstan.neon',
21 | 'phpunit.xml.dist',
22 | ];
23 |
24 | /**
25 | * @param string $file
26 | *
27 | * @return string
28 | */
29 | protected static function normalizeSourceFile(string $file): string
30 | {
31 | return sprintf(str_replace('/', DIRECTORY_SEPARATOR, '%s/../dist/%s'), __DIR__, $file);
32 | }
33 |
34 | /**
35 | * @param string $file
36 | *
37 | * @return string
38 | */
39 | protected static function normalizeDestinationFile(string $file): string
40 | {
41 | return sprintf(str_replace('/', DIRECTORY_SEPARATOR, '%s/%s'), getcwd(), $file);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/Command/InstallCommand.php:
--------------------------------------------------------------------------------
1 |
14 | */
15 | final class InstallCommand extends AbstractCommand
16 | {
17 | /**
18 | * {@inheritdoc}
19 | */
20 | protected static $defaultName = 'install';
21 |
22 | /**
23 | * {@inheritdoc}
24 | */
25 | protected function configure(): void
26 | {
27 | $this
28 | ->setDescription('Create configuration files of SymfonyGrumPHP')
29 | ->setHelp('The install command moves preconfigured files to root folder of a project.');
30 | }
31 |
32 | /**
33 | * {@inheritdoc}
34 | */
35 | protected function execute(InputInterface $input, OutputInterface $output)
36 | {
37 | $helper = $this->getHelper('question');
38 |
39 | $filesystem = new Filesystem();
40 | foreach (self::CONF_FILES as $file) {
41 | $sourceFile = self::normalizeSourceFile($file);
42 | $destinationFile = self::normalizeDestinationFile($file);
43 |
44 | if ($filesystem->exists($destinationFile)) {
45 | $questionOverride = new ConfirmationQuestion(
46 | sprintf('File [%s] exists. Do you want override file? (yes/no) [yes]: ', $file)
47 | );
48 |
49 | if ($helper->ask($input, $output, $questionOverride)) {
50 | $filesystem->rename($destinationFile, sprintf('%s.scbak', $destinationFile), true);
51 | }
52 | }
53 |
54 | $filesystem->copy($sourceFile, $destinationFile);
55 |
56 | if ('phpstan.neon' === $file) {
57 | $this->modifyNeonFile($destinationFile);
58 | }
59 |
60 | $output->writeln(sprintf('File [%s] has been created.', $file));
61 | }
62 |
63 | return 0;
64 | }
65 |
66 | /**
67 | * @param string $destinationFile
68 | */
69 | private function modifyNeonFile(string $destinationFile): void
70 | {
71 | $symfonyKernel = 'Symfony\Component\HttpKernel\Kernel';
72 | if (class_exists($symfonyKernel)) {
73 | $containerXmlPath = '%rootDir%/../../../var/cache/dev/srcDevDebugProjectContainer.xml';
74 |
75 | if (version_compare($symfonyKernel::VERSION, '4.2.0', '>=')) {
76 | $containerXmlPath = '%rootDir%/../../../var/cache/dev/srcApp_KernelDevDebugContainer.xml';
77 | }
78 |
79 | if (version_compare($symfonyKernel::VERSION, '5.0.0', '>=')) {
80 | $containerXmlPath = '%rootDir%/../../../var/cache/dev/App_KernelDevDebugContainer.xml';
81 | }
82 |
83 | file_put_contents($destinationFile, sprintf(' symfony:%s', PHP_EOL), FILE_APPEND);
84 | file_put_contents($destinationFile, sprintf(' container_xml_path: %s', $containerXmlPath), FILE_APPEND);
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/Command/UninstallCommand.php:
--------------------------------------------------------------------------------
1 |
14 | */
15 | final class UninstallCommand extends AbstractCommand
16 | {
17 | /**
18 | * {@inheritdoc}
19 | */
20 | protected static $defaultName = 'uninstall';
21 |
22 | /**
23 | * {@inheritdoc}
24 | */
25 | protected function configure(): void
26 | {
27 | $this
28 | ->setDescription('Remove configuration files of SymfonyGrumPHP')
29 | ->setHelp('The uninstall command removes preconfigured files from root folder of a project.');
30 | }
31 |
32 | /**
33 | * {@inheritdoc}
34 | */
35 | protected function execute(InputInterface $input, OutputInterface $output)
36 | {
37 | $helper = $this->getHelper('question');
38 | $question = new ConfirmationQuestion('Do you want to remove configuration files? (yes/no) [yes]: ');
39 | if ($helper->ask($input, $output, $question)) {
40 | $filesystem = new Filesystem();
41 | foreach (self::CONF_FILES as $file) {
42 | $destinationFile = self::normalizeDestinationFile($file);
43 | $filesystem->remove($destinationFile);
44 | $filesystem->remove(sprintf('%s.scbak', $file));
45 | $output->writeln(sprintf('Files [%s, %s.scbak] have been deleted.', $file, $file));
46 | }
47 | }
48 |
49 | return 0;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/dist/.php_cs:
--------------------------------------------------------------------------------
1 | exclude(['var', 'public', 'vendor'])
6 | ->in(__DIR__);
7 |
8 | return PhpCsFixer\Config::create()
9 | ->setFinder($finder);
10 | // @codeCoverageIgnoreEnd
11 |
--------------------------------------------------------------------------------
/src/dist/grumphp.yml:
--------------------------------------------------------------------------------
1 | # https://github.com/phpro/grumphp
2 | grumphp:
3 | stop_on_failure: false
4 | process_timeout: 120
5 | parallel:
6 | enabled: true
7 | max_workers: 20
8 | # https://github.com/phpro/grumphp/blob/master/doc/tasks.md
9 | tasks:
10 | clover_coverage:
11 | clover_file: ./build/logs/clover.xml
12 | level: 70
13 | metadata:
14 | priority: 1
15 | git_blacklist:
16 | keywords:
17 | - "die\\("
18 | - "var_dump\\("
19 | - "exit;"
20 | - "echo "
21 | - "dump\\("
22 | - "dd\\("
23 | regexp_type: G
24 | whitelist_patterns:
25 | - /^public\/(.*)/
26 | - /^vendor\/(.*)/
27 | metadata:
28 | priority: 999
29 | phpcpd:
30 | directory: ['.']
31 | exclude: ['vendor', 'public', 'var', 'config', 'bin', 'translations', 'src/Presentation/Translations', 'src/Migrations', 'src/Infrastructure/Migrations', 'tests', 'src/DataFixtures', 'migrations']
32 | fuzzy: false
33 | min_lines: 5
34 | min_tokens: 50
35 | metadata:
36 | priority: 999
37 | phpcsfixer:
38 | rules:
39 | - '@PhpCsFixer'
40 | - -multiline_whitespace_before_semicolons
41 | - -php_unit_internal_class
42 | - -php_unit_test_class_requires_covers
43 | - -no_superfluous_phpdoc_tags
44 | - '@DoctrineAnnotation'
45 | verbose: true
46 | diff: true
47 | config: .php_cs
48 | metadata:
49 | priority: 999
50 | phplint:
51 | triggered_by: ['php', 'phtml', 'php3', 'php4', 'php5']
52 | metadata:
53 | priority: 999
54 | phpmd:
55 | exclude: ['tests', 'config', 'var', 'src/Migrations', 'src/Infrastructure/Migrations', 'migrations']
56 | ruleset: ['cleancode', 'codesize', 'controversial', 'design', 'unusedcode']
57 | metadata:
58 | priority: 999
59 | phpstan:
60 | configuration: phpstan.neon
61 | level: 7
62 | memory_limit: '-1'
63 | metadata:
64 | priority: 999
65 | phpunitbridge:
66 | config_file: phpunit.xml.dist
67 | testsuite: Application
68 | always_execute: true
69 | metadata:
70 | priority: 999
71 | securitychecker_enlightn:
72 | lockfile: composer.lock
73 | run_always: false
74 | metadata:
75 | priority: 999
76 | shell:
77 | scripts:
78 | - ['-c', './vendor/bin/simple-phpunit --coverage-clover ./build/logs/clover.xml']
79 | metadata:
80 | priority: 2
81 | # https://github.com/phpro/grumphp/blob/master/doc/testsuites.md
82 | testsuites:
83 | security:
84 | tasks:
85 | - securitychecker_enlightn
86 | phpunitbridge:
87 | tasks:
88 | - phpunitbridge
89 | phpcsmd:
90 | tasks:
91 | - phpcsfixer
92 | - phpmd
93 | no-phpunitbridge:
94 | tasks:
95 | - git_blacklist
96 | - phpcpd
97 | - phpcsfixer
98 | - phplint
99 | - phpmd
100 | - phpstan
101 | - securitychecker_enlightn
102 | phpcsfixer:
103 | tasks:
104 | - phpcsfixer
105 | phpstan:
106 | tasks:
107 | - phpstan
108 | coverage:
109 | tasks:
110 | - shell
111 | - clover_coverage
112 | no-coverage:
113 | tasks:
114 | - git_blacklist
115 | - phpcpd
116 | - phpcsfixer
117 | - phplint
118 | - phpmd
119 | - phpstan
120 | - phpunitbridge
121 | - securitychecker_enlightn
122 |
--------------------------------------------------------------------------------
/src/dist/phpstan.neon:
--------------------------------------------------------------------------------
1 | includes:
2 | - vendor/phpstan/phpstan-doctrine/extension.neon
3 | - vendor/phpstan/phpstan-doctrine/rules.neon
4 | - vendor/phpstan/phpstan-phpunit/extension.neon
5 | - vendor/phpstan/phpstan-phpunit/rules.neon
6 | - vendor/phpstan/phpstan-symfony/extension.neon
7 | - vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon
8 |
9 | parameters:
10 | checkGenericClassInNonGenericObjectType: false
11 | inferPrivatePropertyTypeFromConstructor: true
12 | checkMissingIterableValueType: false
13 | excludes_analyse:
14 | - %rootDir%/../../../bin/*
15 | - %rootDir%/../../../var/*
16 | - %rootDir%/../../../public/*
17 | - %rootDir%/../../../config/*
18 | - %rootDir%/../../../vendor/*
19 | - %rootDir%/../../../tests/*
20 | - %rootDir%/../../../php_cs.php
21 | ignoreErrors:
22 | - '#PHPDoc tag @return with type object is not subtype of native type#'
23 | - '#Method .* should return .* but returns object#'
24 | - '#Method .* should return .* but returns .*ObjectRepository#'
25 | - '#PHPDoc tag @return with type .*ObjectRepository is not subtype of native type .*Repository#'
26 | - '#PHPDoc tag @throws with type .* is not subtype of Throwable#'
27 | - '#call_user_func_array expects callable\(\)#'
28 | - '#expects App\\Entity\\User, Symfony\\Component\\Security\\Core\\User\\UserInterface given.#'
29 | - '#ftp_fput expects resource#'
30 | - '#Call to an undefined method Doctrine\\ORM\\Event\\LifecycleEventArgs::getNewValue\(\)#'
31 | - '#Call to an undefined method Doctrine\\ORM\\Event\\LifecycleEventArgs::getOldValue\(\)#'
32 | - '#Property .*\\Entity\\.* has no typehint specified.#'
33 | - '#Call to an undefined method Doctrine\\Persistence\\ObjectRepositor.*#'
34 | - '#Method App\\.*Repository\(\).*should return App\\Repository\\.*Repository but returns Doctrine\\ORM\\EntityRepository.*#'
35 | - '#Symfony\\Component\\Security\\Core\\User\\UserInterface is not subtype of#'
36 | - '#Call to an undefined method Knp\\Bundle\\PaginatorBundle\\Pagination\\SlidingPaginationInterface.*#'
37 | - '#Call to an undefined method DateTimeInterface::add\(\)#'
38 | - '#string\|Stringable\|Symfony\\Component\\Security\\Core\\User\\UserInterface#'
39 | - '#Variable .* in PHPDoc tag @var does not exist#'
40 |
--------------------------------------------------------------------------------
/src/dist/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | tests/
24 |
25 |
26 |
27 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
43 |
44 | .
45 |
46 |
47 |
48 | ./tests
49 | ./vendor
50 | ./public
51 | ./config
52 | ./var
53 | ./bin
54 | ./migrations
55 | ./src/Infrastructure/Migrations
56 | ./src/Migrations
57 | ./src/DataFixtures
58 | ./src/Entity
59 | ./src/Domain/Entity
60 | ./src/DTO
61 | ./src/Kernel.php
62 | ./src/dist
63 | ./php_cs.php
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/tests/Command/InstallCommandTest.php:
--------------------------------------------------------------------------------
1 | assertSame('install', $command->getName());
19 | }
20 |
21 | public function testExecute()
22 | {
23 | $application = new Application();
24 | $application->add(new InstallCommand());
25 |
26 | $command = $application->find('install');
27 | $commandTester = new CommandTester($command);
28 | $commandTester->setInputs(['yes', 'yes', 'yes', 'yes', 'yes']);
29 | $commandTester->execute(['command' => $command->getName()]);
30 |
31 | $this->assertSame(0, $commandTester->getStatusCode());
32 |
33 | $expectedOutput =
34 | 'File [grumphp.yml] exists. Do you want override file? (yes/no) [yes]: File [grumphp.yml] has been created.
35 | File [.php_cs] exists. Do you want override file? (yes/no) [yes]: File [.php_cs] has been created.
36 | File [phpstan.neon] exists. Do you want override file? (yes/no) [yes]: File [phpstan.neon] has been created.
37 | File [phpunit.xml.dist] exists. Do you want override file? (yes/no) [yes]: File [phpunit.xml.dist] has been created.
38 | ';
39 | $this->assertSame($expectedOutput, $commandTester->getDisplay());
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/tests/Command/UninstallCommandTest.php:
--------------------------------------------------------------------------------
1 | assertSame('uninstall', $command->getName());
20 | }
21 |
22 | public function testExecute()
23 | {
24 | $application = new Application();
25 | $application->add(new UninstallCommand());
26 |
27 | $command = $application->find('uninstall');
28 | $commandTester = new CommandTester($command);
29 | $commandTester->setInputs(['yes', 'yes', 'yes', 'yes', 'yes']);
30 | $commandTester->execute(['command' => $command->getName()]);
31 |
32 | $this->assertSame(0, $commandTester->getStatusCode());
33 |
34 | $expectedOutput =
35 | 'Do you want to remove configuration files? (yes/no) [yes]: Files [grumphp.yml, grumphp.yml.scbak] have been deleted.
36 | Files [.php_cs, .php_cs.scbak] have been deleted.
37 | Files [phpstan.neon, phpstan.neon.scbak] have been deleted.
38 | Files [phpunit.xml.dist, phpunit.xml.dist.scbak] have been deleted.
39 | ';
40 | $this->assertSame($expectedOutput, $commandTester->getDisplay());
41 |
42 | // revert removed files
43 | $application->add(new InstallCommand());
44 |
45 | $command = $application->find('install');
46 | $commandTester = new CommandTester($command);
47 | $commandTester->setInputs(['yes', 'yes', 'yes', 'yes', 'yes']);
48 | $commandTester->execute(['command' => $command->getName()]);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 |