diff --git a/.gitignore b/.gitignore
index 7d5e145..fff9157 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
.idea/
-composer.lock
.phpcs.cache
+.phpunit.cache
+composer.lock
+tests/coverage
vendor/
\ No newline at end of file
diff --git a/README.md b/README.md
index 68b949f..0e1e6e0 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
# Composer i18n Scripts
Simplify the internationalization of your WordPress plugin or theme using WP-CLI — powered by Composer.
+
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index 0ad9c3e..9d8a25f 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -1,4 +1,4 @@
parameters:
- level: 8
+ level: 10
paths:
- src/
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 5e76c56..ce0df9c 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,10 +1,25 @@
-
-
+
+
-
+
tests
-
\ No newline at end of file
+
+
+
+ src
+
+
+
diff --git a/src/Commands/CreatePoCommand.php b/src/Commands/CreatePoCommand.php
index 791c9a7..aac1f7c 100644
--- a/src/Commands/CreatePoCommand.php
+++ b/src/Commands/CreatePoCommand.php
@@ -18,6 +18,8 @@
*/
class CreatePoCommand extends CustomCommand {
+ const DEFAULT_LANGUAGE = 'invalid_LOCALE';
+
/**
* Configures the command.
*/
@@ -54,6 +56,9 @@ protected function configure(): void {
*/
protected function command( I18nConfig $config, InputInterface $input ): string {
$locale = $input->getArgument( 'locale' );
+ if ( empty( $locale ) || ! is_string( $locale ) ) {
+ $locale = self::DEFAULT_LANGUAGE;
+ }
return sprintf(
'if [ ! -e %1$s ]; then cp %2$s %1$s; fi',
diff --git a/src/Commands/CustomCommand.php b/src/Commands/CustomCommand.php
index 714be71..6b255e8 100644
--- a/src/Commands/CustomCommand.php
+++ b/src/Commands/CustomCommand.php
@@ -69,7 +69,10 @@ protected function execute( InputInterface $input, OutputInterface $output ): in
$output->writeln( 'Running: ' . $command . '' );
- $this->runner->exec( $command, $output_lines, $exit_code );
+ $output_lines = [];
+ $exit_code = 0;
+
+ $this->runner->exec( $command, $output_lines, $exit_code );
foreach ( $output_lines as $line ) {
$output->writeln( $line );
diff --git a/src/ShellRunner.php b/src/ShellRunner.php
index b26470d..4869831 100644
--- a/src/ShellRunner.php
+++ b/src/ShellRunner.php
@@ -18,11 +18,11 @@ class ShellRunner {
* Executes a shell command.
*
* @param string $command The command to execute.
- * @param ?string[] $output The output in an array.
- * @param ?int $result_code The result code of the command execution.
+ * @param string[] $output The output in an array.
+ * @param int $result_code The result code of the command execution.
* @return void
*/
- public function exec( string $command, ?array &$output, ?int &$result_code ): void {
+ public function exec( string $command, array &$output, int &$result_code ): void {
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.system_calls_exec
exec( $command, $output, $result_code );
}
diff --git a/tests/Commands/CreatePoCommandTest.php b/tests/Commands/CreatePoCommandTest.php
new file mode 100644
index 0000000..731a724
--- /dev/null
+++ b/tests/Commands/CreatePoCommandTest.php
@@ -0,0 +1,44 @@
+createMock(ShellRunner::class);
+ $runner->method('exec')
+ ->willReturnCallback(function ($cmd, &$output, &$exitCode) {
+ $output = ['Mocked .po creation'];
+ $exitCode = 0;
+ });
+
+ $command = new CreatePoCommand($runner);
+
+ $this->application = new Application();
+ $this->application->setAutoExit(false); // Important for tests
+ $this->application->add($command);
+ }
+
+ public function testCommandIsRegisteredAndConfigured(): void {
+ $command = $this->application->find( 'i18n:create-po' );
+
+ $this->assertSame( 'i18n:create-po', $command->getName() );
+ $this->assertNotEmpty( $command->getDescription() );
+ $this->assertNotEmpty( $command->getHelp() );
+ }
+}
diff --git a/tests/Commands/MakeJsonCommandTest.php b/tests/Commands/MakeJsonCommandTest.php
new file mode 100644
index 0000000..d3e9192
--- /dev/null
+++ b/tests/Commands/MakeJsonCommandTest.php
@@ -0,0 +1,44 @@
+createMock(ShellRunner::class);
+ $runner->method('exec')
+ ->willReturnCallback(function ($cmd, &$output, &$exitCode) {
+ $output = ['Mocked .json generation'];
+ $exitCode = 0;
+ });
+
+ $command = new MakeJsonCommand($runner);
+
+ $this->application = new Application();
+ $this->application->setAutoExit(false); // Important for tests
+ $this->application->add($command);
+ }
+
+
+ public function testCommandIsRegisteredAndConfigured(): void {
+ $command = $this->application->find( 'i18n:make-json' );
+
+ $this->assertSame( 'i18n:make-json', $command->getName() );
+ $this->assertNotEmpty( $command->getDescription() );
+ $this->assertNotEmpty( $command->getHelp() );
+ }
+}
diff --git a/tests/Commands/MakeMoCommandTest.php b/tests/Commands/MakeMoCommandTest.php
new file mode 100644
index 0000000..d6e2594
--- /dev/null
+++ b/tests/Commands/MakeMoCommandTest.php
@@ -0,0 +1,43 @@
+createMock(ShellRunner::class);
+ $runner->method('exec')
+ ->willReturnCallback(function ($cmd, &$output, &$exitCode) {
+ $output = ['Mocked .mo generation'];
+ $exitCode = 0;
+ });
+
+ $command = new MakeMoCommand($runner);
+
+ $this->application = new Application();
+ $this->application->setAutoExit(false); // Important for tests
+ $this->application->add($command);
+ }
+
+ public function testCommandIsRegisteredAndConfigured(): void {
+ $command = $this->application->find( 'i18n:make-mo' );
+
+ $this->assertSame( 'i18n:make-mo', $command->getName() );
+ $this->assertNotEmpty( $command->getDescription() );
+ $this->assertNotEmpty( $command->getHelp() );
+ }
+}
diff --git a/tests/Commands/MakePhpCommandTest.php b/tests/Commands/MakePhpCommandTest.php
new file mode 100644
index 0000000..0bc7c9f
--- /dev/null
+++ b/tests/Commands/MakePhpCommandTest.php
@@ -0,0 +1,44 @@
+createMock(ShellRunner::class);
+ $runner->method('exec')
+ ->willReturnCallback(function ($cmd, &$output, &$exitCode) {
+ $output = ['Mocked .php generation'];
+ $exitCode = 0;
+ });
+
+ $command = new MakePhpCommand($runner);
+
+ $this->application = new Application();
+ $this->application->setAutoExit(false); // Important for tests
+ $this->application->add($command);
+ }
+
+ public function testCommandIsRegisteredAndConfigured(): void {
+ $command = $this->application->find( 'i18n:make-php' );
+
+ $this->assertSame( 'i18n:make-php', $command->getName() );
+ $this->assertNotEmpty( $command->getDescription() );
+ $this->assertNotEmpty( $command->getHelp() );
+ }
+}
diff --git a/tests/Commands/MakePotCommandTest.php b/tests/Commands/MakePotCommandTest.php
index 9927185..2a10780 100644
--- a/tests/Commands/MakePotCommandTest.php
+++ b/tests/Commands/MakePotCommandTest.php
@@ -10,35 +10,35 @@
use lloc\ComposerI18nScripts\Commands\MakePotCommand;
use lloc\ComposerI18nScripts\ShellRunner;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Application;
-use Symfony\Component\Console\Tester\CommandTester;
+#[CoversClass(MakePotCommand::class)]
class MakePotCommandTest extends TestCase {
- public function testCommandIsRegisteredAndConfigured(): void {
- $runner = new ShellRunner();
- $application = new Application();
- $application->add( new MakePotCommand($runner) );
+ protected Application $application;
- $command = $application->find( 'i18n:make-pot' );
- $this->assertSame( 'i18n:make-pot', $command->getName() );
- $this->assertNotEmpty( $command->getDescription() );
- $this->assertNotEmpty( $command->getHelp() );
- }
+ protected function setUp(): void {
+ $runner = $this->createMock(ShellRunner::class);
+ $runner->method('exec')
+ ->willReturnCallback(function ($cmd, &$output, &$exitCode) {
+ $output = ['Mocked .pot generation'];
+ $exitCode = 0;
+ });
- public function testCommandExecutionReturnsSuccess(): void {
- $runner = new ShellRunner();
- $application = new Application();
- $application->add( new MakePotCommand($runner) );
+ $command = new MakePotCommand($runner);
- $command = $application->find( 'i18n:make-pot' );
- $tester = new CommandTester( $command );
+ $this->application = new Application();
+ $this->application->setAutoExit(false); // Important for tests
+ $this->application->add($command);
+ }
- // You may need to mock or override shell exec inside the command to make this testable
- $tester->execute( array() );
+ public function testCommandIsRegisteredAndConfigured(): void {
+ $command = $this->application->find( 'i18n:make-pot' );
- // Just test if it runs (for now)
- $this->assertSame( 0, $tester->getStatusCode() );
+ $this->assertSame( 'i18n:make-pot', $command->getName() );
+ $this->assertNotEmpty( $command->getDescription() );
+ $this->assertNotEmpty( $command->getHelp() );
}
}
diff --git a/tests/Commands/UpdatePoCommandTest.php b/tests/Commands/UpdatePoCommandTest.php
new file mode 100644
index 0000000..2d4c3f7
--- /dev/null
+++ b/tests/Commands/UpdatePoCommandTest.php
@@ -0,0 +1,43 @@
+createMock(ShellRunner::class);
+ $runner->method('exec')
+ ->willReturnCallback(function ($cmd, &$output, &$exitCode) {
+ $output = ['Mocked .po update'];
+ $exitCode = 0;
+ });
+
+ $command = new UpdatePoCommand($runner);
+
+ $this->application = new Application();
+ $this->application->setAutoExit(false); // Important for tests
+ $this->application->add($command);
+ }
+
+ public function testCommandIsRegisteredAndConfigured(): void {
+ $command = $this->application->find( 'i18n:update-po' );
+
+ $this->assertSame( 'i18n:update-po', $command->getName() );
+ $this->assertNotEmpty( $command->getDescription() );
+ $this->assertNotEmpty( $command->getHelp() );
+ }
+}