Repository: facile-it/paraunit (php)

Issue:
Implement passthrough option
We could copy the `--passthrough` option from Paratest: it just forwards its value as additional options to the PHPUnit CLI, so that we can drop any particular option that doesn't do anything on Paraunit.

Pull request description:
Pass through
Fixes #174 

Patch:
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 906e5167..8d620578 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -1,21 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<files psalm-version="5.6.0@e784128902dfe01d489c4123d69918a9f3c1eac5">
+<files psalm-version="5.7.7@e028ba46ba0d7f9a78bc3201c251e137383e145f">
   <file src="src/Configuration/PHPUnitConfig.php">
     <DocblockTypeContradiction>
-      <code>$extension-&gt;attributes</code>
+      <code><![CDATA[$extension->attributes]]></code>
     </DocblockTypeContradiction>
     <RedundantConditionGivenDocblockType>
-      <code>$extension-&gt;attributes?-&gt;getNamedItem('class')</code>
+      <code><![CDATA[$extension->attributes?->getNamedItem('class')]]></code>
     </RedundantConditionGivenDocblockType>
   </file>
   <file src="src/Configuration/ParallelConfiguration.php">
     <MixedArgument>
-      <code>$input-&gt;getArgument('stringFilter')</code>
-      <code>$input-&gt;getOption('chunk-size')</code>
-      <code>$input-&gt;getOption('configuration') ?? '.'</code>
-      <code>$input-&gt;getOption('logo')</code>
-      <code>$input-&gt;getOption('parallel')</code>
-      <code>$input-&gt;getOption('testsuite')</code>
+      <code><![CDATA[$input->getArgument('stringFilter')]]></code>
+      <code><![CDATA[$input->getOption('chunk-size')]]></code>
+      <code><![CDATA[$input->getOption('configuration') ?? '.']]></code>
+      <code><![CDATA[$input->getOption('logo')]]></code>
+      <code><![CDATA[$input->getOption('parallel')]]></code>
+      <code><![CDATA[$input->getOption('pass-through')]]></code>
+      <code><![CDATA[$input->getOption('testsuite')]]></code>
     </MixedArgument>
   </file>
   <file src="src/Coverage/CoverageFetcher.php">
@@ -25,8 +26,8 @@
   </file>
   <file src="src/File/Cleaner.php">
     <MixedArgument>
-      <code>$file-&gt;getRealPath()</code>
-      <code>$file-&gt;getRealPath()</code>
+      <code><![CDATA[$file->getRealPath()]]></code>
+      <code><![CDATA[$file->getRealPath()]]></code>
     </MixedArgument>
     <MixedAssignment>
       <code>$file</code>
@@ -39,12 +40,12 @@
   </file>
   <file src="src/Filter/Filter.php">
     <PossiblyNullOperand>
-      <code>$fileNode-&gt;nodeValue</code>
+      <code><![CDATA[$fileNode->nodeValue]]></code>
     </PossiblyNullOperand>
   </file>
   <file src="src/Process/CommandLine.php">
     <PossiblyNullOperand>
-      <code>$option-&gt;getValue()</code>
+      <code><![CDATA[$option->getValue()]]></code>
     </PossiblyNullOperand>
   </file>
   <file src="src/Process/SymfonyProcessWrapper.php">
diff --git a/src/Command/ParallelCommand.php b/src/Command/ParallelCommand.php
index f36d1df0..6f32ff19 100644
--- a/src/Command/ParallelCommand.php
+++ b/src/Command/ParallelCommand.php
@@ -78,6 +78,7 @@ class ParallelCommand extends Command
         $this->addOption('chunk-size', null, InputOption::VALUE_REQUIRED, 'Number of test files in chunk', 1);
         $this->addOption('debug', null, InputOption::VALUE_NONE, 'Print verbose debug output');
         $this->addOption('logo', null, InputOption::VALUE_NONE, 'Print the Shark logo at the top');
+        $this->addOption('pass-through', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Inject options to be passed directly to the underlying PHPUnit processes');
 
         foreach ($this->phpunitOptions as $option) {
             $this->addOption(
diff --git a/src/Configuration/DependencyInjection/ParallelContainerDefinition.php b/src/Configuration/DependencyInjection/ParallelContainerDefinition.php
index 721896b1..32f76384 100644
--- a/src/Configuration/DependencyInjection/ParallelContainerDefinition.php
+++ b/src/Configuration/DependencyInjection/ParallelContainerDefinition.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace Paraunit\Configuration\DependencyInjection;
 
 use Paraunit\Configuration\ChunkSize;
+use Paraunit\Configuration\PassThrough;
 use Paraunit\Configuration\PHPUnitBinFile;
 use Paraunit\Configuration\PHPUnitConfig;
 use Paraunit\Configuration\TempFilenameFactory;
@@ -101,6 +102,9 @@ class ParallelContainerDefinition
 
         $container->autowire(ChunkSize::class)
             ->setArgument('$chunkSize', '%paraunit.chunk_size%');
+
+        $container->register(PassThrough::class)
+            ->setArguments(['%paraunit.pass_through%']);
     }
 
     private function configureEventDispatcher(ContainerBuilder $container): void
diff --git a/src/Configuration/ParallelConfiguration.php b/src/Configuration/ParallelConfiguration.php
index ed490efe..07938e7c 100644
--- a/src/Configuration/ParallelConfiguration.php
+++ b/src/Configuration/ParallelConfiguration.php
@@ -70,6 +70,7 @@ class ParallelConfiguration
         $containerBuilder->setParameter('paraunit.testsuite', $input->getOption('testsuite'));
         $containerBuilder->setParameter('paraunit.string_filter', $input->getArgument('stringFilter'));
         $containerBuilder->setParameter('paraunit.show_logo', $input->getOption('logo'));
+        $containerBuilder->setParameter('paraunit.pass_through', $input->getOption('pass-through'));
 
         if ($input->getOption('debug')) {
             $this->enableDebugMode($containerBuilder);
diff --git a/src/Configuration/PassThrough.php b/src/Configuration/PassThrough.php
new file mode 100644
index 00000000..72cba51f
--- /dev/null
+++ b/src/Configuration/PassThrough.php
@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Paraunit\Configuration;
+
+class PassThrough
+{
+    /** @var list<string> */
+    public readonly array $options;
+
+    /**
+     * @param string[]|null $options
+     */
+    public function __construct(?array $options = [])
+    {
+        $this->options = array_values($options ?? []);
+    }
+}
diff --git a/src/Process/ProcessFactory.php b/src/Process/ProcessFactory.php
index 73563462..1318883d 100644
--- a/src/Process/ProcessFactory.php
+++ b/src/Process/ProcessFactory.php
@@ -6,6 +6,7 @@ namespace Paraunit\Process;
 
 use Paraunit\Configuration\ChunkSize;
 use Paraunit\Configuration\EnvVariables;
+use Paraunit\Configuration\PassThrough;
 use Paraunit\Configuration\PHPUnitConfig;
 use Paraunit\Configuration\TempFilenameFactory;
 use Paraunit\Coverage\CoverageDriver;
@@ -23,7 +24,8 @@ class ProcessFactory
         private readonly CommandLine $cliCommand,
         PHPUnitConfig $phpunitConfig,
         TempFilenameFactory $tempFilenameFactory,
-        private readonly ChunkSize $chunkSize
+        private readonly ChunkSize $chunkSize,
+        private readonly PassThrough $passThrough,
     ) {
         $this->baseCommandLine = array_merge($this->cliCommand->getExecutable(), $this->cliCommand->getOptions($phpunitConfig));
         $this->environmentVariables = [
@@ -57,6 +59,7 @@ class ProcessFactory
             $command = array_merge(
                 $this->baseCommandLine,
                 [$testFilePath],
+                $this->passThrough->options,
                 $this->cliCommand->getSpecificOptions($testFilePath)
             );
         }


Test patch:
diff --git a/tests/PHPT/pass-through.phpt b/tests/PHPT/pass-through.phpt
new file mode 100644
index 00000000..7bb3699a
--- /dev/null
+++ b/tests/PHPT/pass-through.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Execute the run command with the --pass-through option
+--FILE--
+<?php
+
+require_once __DIR__ . '/../../src/Bin/paraunit';
+--ARGS--
+run IntentionalWarningTestStub -c tests/Stub/phpunit_for_stubs.xml --pass-through=--stop-on-warning
+--EXPECTF--
+PARAUNIT v%s
+by Francesco Panina, Alessandro Lai & Shark Dev Team @ Facile.it
+W %w 1
+
+
+Execution time -- 00:00:%d
+
+Executed: 1 test classes, 1 tests
+
+Warnings output:
+
+1) Tests\Stub\IntentionalWarningTestStub::testWithIntentionalWarning
+This is an intentional warning
+
+1 files with WARNINGS:
+ Tests\Stub\IntentionalWarningTestStub::testWithIntentionalWarning
diff --git a/tests/Unit/Configuration/CoverageConfigurationTest.php b/tests/Unit/Configuration/CoverageConfigurationTest.php
index 1705203a..a550e9d9 100644
--- a/tests/Unit/Configuration/CoverageConfigurationTest.php
+++ b/tests/Unit/Configuration/CoverageConfigurationTest.php
@@ -133,6 +133,7 @@ class CoverageConfigurationTest extends BaseUnitTestCase
             'ansi',
             'logo',
             'chunk-size',
+            'pass-through',
         ];
 
         foreach ($options as $optionName) {
@@ -197,6 +198,7 @@ class CoverageConfigurationTest extends BaseUnitTestCase
             'crap4j',
             'php',
             'chunk-size',
+            'pass-through',
         ];
 
         foreach ($options as $optionName) {
diff --git a/tests/Unit/Process/ProcessFactoryTest.php b/tests/Unit/Process/ProcessFactoryTest.php
index 657554ba..e100add9 100644
--- a/tests/Unit/Process/ProcessFactoryTest.php
+++ b/tests/Unit/Process/ProcessFactoryTest.php
@@ -6,6 +6,7 @@ namespace Tests\Unit\Process;
 
 use Paraunit\Configuration\ChunkSize;
 use Paraunit\Configuration\EnvVariables;
+use Paraunit\Configuration\PassThrough;
 use Paraunit\Configuration\PHPUnitConfig;
 use Paraunit\Configuration\TempFilenameFactory;
 use Paraunit\Coverage\CoverageDriver;
@@ -44,7 +45,8 @@ class ProcessFactoryTest extends BaseUnitTestCase
             $cliCommand->reveal(),
             $phpUnitConfig->reveal(),
             $tempFilenameFactory->reveal(),
-            $this->mockChunkSize(false)
+            $this->mockChunkSize(false),
+            new PassThrough(['--one', '--two=yes']),
         );
 
         $processWrapper = $factory->create('TestTest.php');
@@ -60,6 +62,8 @@ class ProcessFactoryTest extends BaseUnitTestCase
         $commandLine = $processWrapper->getCommandLine();
         $this->assertStringContainsString('TestTest2.php', $commandLine);
         $this->assertStringContainsString('--specific=value-for-TestTest2.php', $commandLine);
+        $this->assertStringContainsString('--one', $commandLine);
+        $this->assertStringContainsString('--two=yes', $commandLine);
     }
 
     #[DataProvider('coverageDriverDataProvider')]
@@ -84,6 +88,7 @@ class ProcessFactoryTest extends BaseUnitTestCase
             $phpUnitConfig->reveal(),
             $tempFilenameFactory->reveal(),
             $this->prophesize(ChunkSize::class)->reveal(),
+            new PassThrough(),
         );
 
         $this->assertEquals([
@@ -126,7 +131,8 @@ class ProcessFactoryTest extends BaseUnitTestCase
             $cliCommand->reveal(),
             $phpUnitConfig->reveal(),
             $tempFilenameFactory->reveal(),
-            $this->mockChunkSize(true)
+            $this->mockChunkSize(true),
+            new PassThrough(),
         );
 
         $processWrapper = $factory->create('phpunit.xml');