How to hide or delete the defaults available console commands? - php

I created a new Symfony 4 project via symfony new my_project_name.
Currently when I execute ./bin/console, the output shows
I will create some custom console commands and I want show only my custom commands when I do ./bin/console
Maybe I should create a custom executable 'console' from scratch, but I don't know how do that.

You are creating a complete Symfony application, so all the commands provided by the included packages are available.
Instead of starting from a framework and trying to trim down the parts you do not want, you need to start from further down to have a really barebones project.
Bootstrapping the project:
First, do not use symfony command, no need. Plain old composer will do the trick.
On an empty directory, execute:
composer require symfony/console
This will import the only dependency needed for a console project, and do the basic bootstrapping for your autoloader.
In composer.json, add the following:
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
Command class
You'll need one or more commands to actually add to your application. Let's start with a fully fledged greeting application. Create the file src/Greet.php within your project:
declare(strict_types=1);
namespace App;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class Greet extends Symfony\Component\Console\Command\Command
{
protected function configure()
{
$this->addArgument('person', InputArgument::OPTIONAL, 'Name of the Entity being greeted', 'World');
$this->addOption('greeting', 'g', InputOption::VALUE_OPTIONAL, 'How to greet the entity', 'Hello');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$greeting = $input->getOption('greeting');
$entity = $input->getArgument('person');
$output->writeln("<info>$greeting $entity!</info>");
}
}
This is a basic command that will print "Hello World!" if executed without any option or argument, will accept one argument use instead of "World", and one option to set the greeting instead of "Hello".
Console Application
On the project's root, create a file app.php.
require __DIR__ . '/vendor/autoload.php';
$app = new Symfony\Component\Console\Application('Hello World App', '1.0.0');
$app->add((new App\Greet('greet')));
$app->run();
This is be a very short script, so let's go line by line
Require the autoloader. This script is the entry point for the application, so we need to execute the autoloader.
Instantiate the application. This creates a new instance of the Symfony Console application, sets a name and version for the app. This will be used in the "help" printouts for the app.
Add the command. By default, the application has no commands at all. We'll need to add the command we have just created. add() expects a Command instance. We instantiate the command we just created, and we set it to be called by the name "greet".
Run the application
Generate autoloader.
Execute composer dump-autoload so the autoloader for your application is generated.
Execute the script.
If you now execute php app.php you'll get:
Hello World App 1.0.0
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
greet
help Displays help for a command
list Lists commands
Note that the only available command is greet. Which you can use like this:
# php app.php greet
Hello World!
# php app.php greet Alice
Hello Alice!
# php app.php greet Bob -g "Good morning"
Good morning Bob!
# php app.php help greet
Usage:
greet [options] [--] [<person>]
Arguments:
person Name of the Entity being greeted [default: "World"]
Options:
-g, --greeting[=GREETING] How to greet the entity [default: "Hello"]
[... default generic options omitted]

Related

Laravel Dusk says Class 'Tests\Browser\Components\...' could not be found

After I installed laravel-dusk following the official Laravel documentation and run this command:
php artisan make:component CardComponentTest
Then try to run immediately:
php artisan dusk tests/Browser/Components/CardComponentTest.php
I get this error:
Class 'Tests\Browser\Components\CardComponentTest' could not be found in '/var/www/html/tests/Browser/Components/CardComponentTest.php'.
I tested file and path are correct:
ls -l /var/www/html/tests/Browser/Components/CardComponentTest.php
And it says:
-rw-r--r-- 1 djw djw 6917 Dec 3 11:25 /var/www/html/tests/Browser/Components/CardComponentTest.php
So it is exists and readable.
I checked the namespace in the file:
<?php
namespace Tests\Browser\Components;
It also looks good.
I checked the composer.json and in this I have this section:
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
So the file exists, the namespace is good and the namespace is picked up in the composer.json.
I tried to run composer dump-autoload too. All good.
Any ide what's wrong whit this?
the error:
Class 'Tests\Browser\Components\CardComponentTest' could not be found in '/var/www/html/tests/Browser/Components/CardComponentTest.php'.
indicate you don't have CardComponentTest test case. Because CardComponentTest is not test case but just an component/part of test.
As aless said, component is not a test itself. But if you really want to test CardComponentTest you can replace
use Laravel\Dusk\Component as BaseComponent;
class CardComponentTest extends BaseComponent
to :
use Tests\DuskTestCase;
class CardComponentTest extends DuskTestCase
after you do that you can run php artisan dusk tests/Browser/Components/CardComponentTest.php , You just need to add test method first like. An example:
public function testComponentExample()
{
$this->browse(function (Browser $browser) {
$browser->visit('/')
->assertSee('Laravel');
});
}
But create test case in component folder is not best practice. You should create test case like official documentation said. Run dusk:make instead of dusk:component. An example:
php artisan dusk:make SimpleBrowserTest
and now you can run
php artisan dusk tests/Browser/SimpleBrowserTest.php
If you take a look at the documentation, the Component is not a test itself. Hence, you should not name the component "*Test" and you should not try to run the component like a dusk test.
You will use your component in your dusk test as described here:
https://laravel.com/docs/9.x/dusk#using-components
Components are for repeated actions, like selecting a date in a picker, which is then further used in your test case for example in a form or maybe some change in your UX happens that is assertable.

Why the laravel make:controller command gives Too many arguments, expected arguments "name"

I want to create a controller with a model. I used artisan.
php artisan make:controller –-model=RequestLog --resource ReqLogController
But the result was,
Too many arguments to "make:controller" command, expected arguments "name".
I read the documentation but didn't find a solution.
And I tried php artisan help make:controller, and the result was,
Description:
Create a new controller class
Usage:
make:controller [options] [--] <name>
Arguments:
name The name of the class
Options:
--api Exclude the create and edit methods from the controller
--type=TYPE Manually specify the controller stub file to use
--force Create the class even if the controller already exists
-i, --invokable Generate a single method, invokable controller class
-m, --model[=MODEL] Generate a resource controller for the given model
-p, --parent[=PARENT] Generate a nested resource controller class
-r, --resource Generate a resource controller class
-R, --requests Generate FormRequest classes for store and update
--test Generate an accompanying PHPUnit test for the Controller
--pest Generate an accompanying Pest test for the Controller
-h, --help Display help for the given command. When no command is given display help for the list command
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi|--no-ansi Force (or disable --no-ansi) ANSI output
-n, --no-interaction Do not ask any interactive question
--env[=ENV] The environment the command should run under
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
In my knowledge, the command that I used was correct according to the help.

Writing PHPUnit test for a class which extends another class produces a 'Class not found' error

What I have:
WPKit/Module/AbstractFunctions.php Abstract Class;
wp-content/themes/mytheme/modules/quiz/Functions.php:
use WPKit\Module\AbstractFunctions;
class Functions extends AbstractFunctions { ... }
wp-content/themes/mytheme/tests/quiz/QuizFunctionsTest.php:
require_once dirname(__FILE__) . "/../../modules/quiz/Functions.php";
class QuizFunctionsTest extends TestCase {
public function testGetQuizByID() {
# some code
}
}
When running phpunit QuizFunctionsTest.php, it gives me the following error:
PHP Fatal error: Class '%path%\AbstractFunctions' not found in %path%/modules/quiz/Functions.php on line 18
I tried require_once the missing class but it didn't help. Outside the test class my code works just fine. Any thoughts?
TL;DR: It seems I couldn't get it to work because it was a WordPress setup so what I did was install PHPUnit via wget and use WP-CLI to scaffold theme-tests, then it worked like a charm.
First I installed the PHPUnit from terminal inside my theme directory:
wget -O phpunit https://phar.phpunit.de/phpunit-7.phar
chmod +x phpunit
Next I installed WP-CLI:
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
Next setting up the test suite:
wp scaffold theme-tests your-theme-slug
Also make sure you have svn installed.
In my case (and I found some mention it, too) I had to delete /tmp/wordpress and /tmp/wordpress-tests-lib and re-run the previous command twice because the script somehow didn't download everything.
Notice that you'll have a separate WordPress setup in /tmp/wordpress. In my primary WordPress setup I use WPKit library which is stored in WordPress root near wp-content so I had to copy it to /tmp/wordpress, otherwise my PHPUnit tests couldn't find WPKit files which were included in the classes I had to test.
So when you run wp scaffold it creates bin directory in your theme root. Run the following command from your theme root in order to install the test suite:
bin/install-wp-tests.sh <test-database-name> <user> <password> <host> <wordpress-version>
In my case it looked like:
bin/install-wp-tests.sh wp_test root '' localhost latest
Be sure to use empty database because running PHPUnit clears the database every time so you may lose your data.
After all these actions just run PHPUnit and you should be fine:
./phpunit
It runs tests in your-theme/tests directory. By default it ignores the default test file so use it to make your own simple tests to check everything works.
Whew.
Sources:
https://www.kirstencassidy.com/testing-wordpress-plugins-wp-cli-phpunit/
https://phpunit.de/getting-started/phpunit-7.html
https://wp-cli.org/#installing
https://www.smashingmagazine.com/2017/12/automated-testing-wordpress-plugins-phpunit/

How do I run PHPUnit in Laravel from my Windows Command prompt

I have a Laravel app installed in my directory f:\lara_app. I use PHP artisan serve to run the app. I have Laravel version 5.4.36 (via Composer Install)
I am not trying my hand in using the PHP Unit to do testing. Inside f:/lara_app/tests/Unit/ExampleTest.php, I have the following codes:
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* #return void
*/
public function testBasicTest()
{
$this->assertTrue(true);
}
public function myFirstTest()
{
$value = 'Hello World';
$this->assertTrue( 'Hello' === $value, 'Value should be Hello World');
}
}
I now try to run the test from my command prompt:
f:\lara_app> .vendor/phpunit/phpuni/phpunit
But I'm getting the message below:
'.vendor' is not recognized as an internal or external command, operable program or batch file
How do I run the PHPUnit test?
Thanks in advance
Use quotes:
"./vendor/bin/phpunit"
This should work on windows
f:\lara_app> php vendor/phpunit/phpunit/phpunit
This works for me
C:\code\project-name> vendor\bin\phpunit
For every Laravel project from version 7.x, if you want to run tests you can do one of these:
You can use artisan: php artisan test docs
Or you can use phpunit: if you want to run phpunit on windows, only by typing phpunit, you can create a bat file in your project's main directory by running this command:#echo php vendor\phpunit\phpunit\phpunit > phpunit.bat and then you can type phpunit in your command and enjoy.
Happy Testing...
Also for future readers, you can run it on windows powershell, without having to change anything, if you're in the root directory of your project. Simply Type
./vendor/bin/phpunit
Use quotes or use backslashes. Unlike linux, Windows does not like forward slashes.
Check if you have phpunit in composer.json, and run:
composer update
And then run PHPUnit:
vendor/bin/phpunit

Codeception & Symfony - run Doctrine migrations before tests

I have a Symfony 4 application and Doctrine with Doctrine migrations. I'm introducing Codeception for running API tests, and need to run migrations before the tests run. Since I'm using the Doctrine2 module I don't really want to be also including the DB module as it's not needed for the tests and would require configuring the test database in two different locations.
I am using the Symfony module currently, and I noticed that the Laravel module has a run_database_migrations configuration option.
What is the best way to handle running the Doctrine migrations command in a Symfony app prior to the tests? (bin/console doctrine:migrations:migrate -n is the specific command).
Edit I've got a solution that, although it works, is nowhere near ideal. By using Codeception Customisation I've created the following extension that basically manually execs the underlying Symfony commands.
class DatabaseMigrationExtension extends Extension
{
public static $events = [
Events::SUITE_BEFORE => 'beforeSuite',
];
public function beforeSuite(SuiteEvent $e)
{
echo(exec('bin/console doctrine:database:drop --force') . PHP_EOL);
echo(exec('bin/console doctrine:database:create') . PHP_EOL);
echo(exec('bin/console doctrine:migrations:migrate -n') . PHP_EOL);
}
}
Edit 2 The goal of this is basically to replicate similar functionality to what the Codeception DB module does, which allows you to provide an SQL dump of a database that it automatically uses in the tests, but instead use Doctrine migrations to handle the DB. - https://codeception.com/docs/modules/Db#sql-data-dump
I spent a while trying a couple of different ways to achieve this. I initially used RunProcess however this seemed to cause sporadic issues with the DB being deleted and not recreated, despite using the sleep configuration. I ended up just updating the existing extension to use the CLI module instead, and it works as desired (without having to create scripts or run multiple commands) and without having to use exec.
Final extension;
class DatabaseMigrationExtension extends Extension
{
public static $events = [
Events::SUITE_BEFORE => 'beforeSuite',
];
public function beforeSuite()
{
try {
/** #var \Codeception\Module\Cli $cli */
$cli = $this->getModule('Cli');
$this->writeln('Recreating the DB...');
$cli->runShellCommand('bin/console doctrine:database:drop --if-exists --force');
$cli->seeResultCodeIs(0);
$cli->runShellCommand('bin/console doctrine:database:create');
$cli->seeResultCodeIs(0);
$this->writeln('Running Doctrine Migrations...');
$cli->runShellCommand('bin/console doctrine:migrations:migrate --no-interaction');
$cli->seeResultCodeIs(0);
$this->writeln('Test database recreated');
} catch (\Exception $e) {
$this->writeln(
sprintf(
'An error occurred whilst rebuilding the test database: %s',
$e->getMessage()
)
);
}
}
}
and registered;
// codeception.yml
extensions:
enabled:
- \DatabaseMigrationExtension
Output (-vv or higher also displays the output of the DB & Migration commands);
I always create a bash script to do this, or a Makefile.
bash command
My ./runtests.sh scripts contains
#!/bin/bash
./bin/console command:for:migrations
./bin/phpunit
Makefile
Same with Makefile
.FOO: testsuite
testsuite:
./runtests.sh
or
.FOO: testsuite
testsuite:
./bin/console command:for:migrations
./bin/phpunit
why I prefer Makefile
Recently I added this script in my .bash_profile that allow me to autocomplete from bash all target made in makefile (very easy because you dont need anymore to remember all commands, but just make and tab).
complete -W "`grep -oE '^[a-zA-Z0-9_.-]+:([^=]|$)' Makefile | sed 's/[^a-zA-Z0-9_.-]*$//'`" make
Thus, .. you can create target like:
runtests
runtests_with_fixtures
migrations
runtests_with_migrations
...
and so on
My suggestion is to create your custom and easy way to run commands.
Here a way to run all or just one command usgin make
.FOO: dropforce
dropforce:
bin/console doctrine:database:drop --force
.FOO: dbcreate
dbcreate:
bin/console doctrine:database:create
.FOO: migrate
migrate:
bin/console doctrine:migrations:migrate
.FOO: suite
suite: dropforce dbcreate migrate
With Codeception 4 you can do it without Cli module:
$symfony = $this->getModule('Symfony');
$symfony->runSymfonyConsoleCommand('doctrine:database:drop',['--if-exists'=>true, '--force'=>true]);
$symfony->runSymfonyConsoleCommand('doctrine:database:create');
$symfony->runSymfonyConsoleCommand('doctrine:migrations:migrate', ['--no-interaction'=>true]);

Categories