2222use Symfony \Component \Console \Input \InputInterface ;
2323use Symfony \Component \Console \Input \InputOption ;
2424use Symfony \Component \Console \Output \OutputInterface ;
25- use Symfony \Component \Process \Exception \ProcessFailedException ;
2625use Symfony \Component \Process \Process ;
2726
2827/**
@@ -91,7 +90,6 @@ protected function configure(): void
9190 shortcut: 'p ' ,
9291 mode: InputOption::VALUE_OPTIONAL ,
9392 description: 'Run tests in parallel using ParaTest. Optional number of workers. ' ,
94- default: null ,
9593 );
9694 }
9795
@@ -108,8 +106,28 @@ protected function configure(): void
108106 */
109107 protected function execute (InputInterface $ input , OutputInterface $ output ): int
110108 {
109+ $ arguments = $ this ->buildBaseArguments ($ input );
110+
111+ if (null !== $ input ->getOption ('parallel ' )) {
112+ return $ this ->runParallel ($ input , $ output , $ arguments );
113+ }
114+
111115 $ output ->writeln ('<info>Running PHPUnit tests...</info> ' );
112116
117+ $ command = new Process ([...$ arguments , $ input ->getArgument ('path ' )]);
118+
119+ return parent ::runProcess ($ command , $ output );
120+ }
121+
122+ /**
123+ * Builds the base PHPUnit arguments from input options.
124+ *
125+ * @param InputInterface $input the runtime instruction set from the CLI
126+ *
127+ * @return list<string> the base arguments for PHPUnit
128+ */
129+ private function buildBaseArguments (InputInterface $ input ): array
130+ {
113131 $ arguments = [
114132 $ this ->getAbsolutePath ('vendor/bin/phpunit ' ),
115133 '--configuration= ' . parent ::getConfigFile (self ::CONFIG ),
@@ -124,121 +142,76 @@ protected function execute(InputInterface $input, OutputInterface $output): int
124142 $ arguments [] = '--cache-directory= ' . $ this ->resolvePath ($ input , 'cache-dir ' );
125143 }
126144
127- if ($ input ->getOption ('coverage ' )) {
128- $ output ->writeln (
129- '<info>Generating code coverage reports on path: ' . $ this ->resolvePath ($ input , 'coverage ' ) . '</info> '
130- );
145+ if (null !== $ input ->getOption ('coverage ' )) {
146+ $ coveragePath = $ this ->resolvePath ($ input , 'coverage ' );
131147
132148 foreach ($ this ->getPsr4Namespaces () as $ path ) {
133149 $ arguments [] = '--coverage-filter= ' . $ this ->getAbsolutePath ($ path );
134150 }
135151
136152 $ arguments [] = '--coverage-text ' ;
137- $ arguments [] = '--coverage-html= ' . $ this -> resolvePath ( $ input , ' coverage ' ) ;
138- $ arguments [] = '--testdox-html= ' . $ this -> resolvePath ( $ input , ' coverage ' ) . '/testdox.html ' ;
139- $ arguments [] = '--coverage-clover= ' . $ this -> resolvePath ( $ input , ' coverage ' ) . '/clover.xml ' ;
140- $ arguments [] = '--coverage-php= ' . $ this -> resolvePath ( $ input , ' coverage ' ) . '/coverage.php ' ;
153+ $ arguments [] = '--coverage-html= ' . $ coveragePath ;
154+ $ arguments [] = '--testdox-html= ' . $ coveragePath . '/testdox.html ' ;
155+ $ arguments [] = '--coverage-clover= ' . $ coveragePath . '/clover.xml ' ;
156+ $ arguments [] = '--coverage-php= ' . $ coveragePath . '/coverage.php ' ;
141157 }
142158
143- if ($ input ->getOption ('filter ' )) {
159+ if (null !== $ input ->getOption ('filter ' )) {
144160 $ arguments [] = '--filter= ' . $ input ->getOption ('filter ' );
145161 }
146162
147- $ parallel = $ input ->getOption ('parallel ' );
148-
149- if ($ parallel !== null ) {
150- return $ this ->runParallel ($ input , $ output , $ parallel , $ arguments );
151- }
152-
153- $ command = new Process ([...$ arguments , $ input ->getArgument ('path ' )]);
154-
155- return parent ::runProcess ($ command , $ output );
163+ return $ arguments ;
156164 }
157165
158166 /**
159167 * Executes PHPUnit in parallel mode using ParaTest.
160168 *
161169 * @param InputInterface $input the runtime instruction set from the CLI
162170 * @param OutputInterface $output the console feedback relay
163- * @param mixed $workers the number of workers or empty for auto
164- * @param array<int, string> $baseArguments the base PHPUnit arguments
171+ * @param list<string> $baseArguments the base PHPUnit arguments
165172 *
166173 * @return int the status integer describing the termination code
167174 */
168175 private function runParallel (
169176 InputInterface $ input ,
170177 OutputInterface $ output ,
171- mixed $ workers ,
172178 array $ baseArguments ,
173179 ): int {
174180 $ output ->writeln ('<info>Running PHPUnit tests in parallel mode...</info> ' );
175181
176- $ validParatestOptions = [
177- '--bootstrap ' ,
178- '--configuration ' ,
179- '--cache-directory ' ,
180- '--filter ' ,
181- '--group ' ,
182- '--exclude-group ' ,
183- '--testsuite ' ,
184- '--no-test-tokens ' ,
185- '--stop-on-defect ' ,
186- '--stop-on-error ' ,
187- '--stop-on-failure ' ,
188- '--stop-on-warning ' ,
189- '--stop-on-risky ' ,
190- '--stop-on-skipped ' ,
191- '--stop-on-incomplete ' ,
192- '--fail-on-incomplete ' ,
193- '--fail-on-risky ' ,
194- '--fail-on-skipped ' ,
195- '--fail-on-warning ' ,
196- '--fail-on-deprecation ' ,
197- ];
198-
182+ $ workers = $ input ->getOption ('parallel ' );
199183 $ arguments = [
200184 $ this ->getAbsolutePath ('vendor/bin/paratest ' ),
201185 ];
202186
203- if ($ workers !== null && $ workers !== '' ) {
187+ if (null !== $ workers && '' !== $ workers ) {
204188 $ arguments [] = '--processes= ' . (int ) $ workers ;
205189 }
206190
207- foreach ($ baseArguments as $ arg ) {
208- $ isValid = false ;
209- foreach ($ validParatestOptions as $ option ) {
210- if (str_starts_with ($ arg , $ option )) {
211- $ isValid = true ;
191+ $ arguments [] = '--configuration= ' . parent ::getConfigFile (self ::CONFIG );
192+ $ arguments [] = '--bootstrap= ' . $ this ->resolvePath ($ input , 'bootstrap ' );
212193
213- break ;
214- }
215- }
216-
217- if ($ isValid ) {
218- $ arguments [] = $ arg ;
219- }
194+ if (! $ input ->getOption ('no-cache ' )) {
195+ $ arguments [] = '--cache-directory= ' . $ this ->resolvePath ($ input , 'cache-dir ' );
220196 }
221197
222- $ coverage = $ input ->getOption ('coverage ' );
223- if ($ coverage !== null ) {
224- $ output ->writeln (
225- '<info>Generating code coverage reports on path: ' . $ this ->getAbsolutePath ($ coverage ) . '</info> '
226- );
198+ if (null !== $ input ->getOption ('coverage ' )) {
199+ $ coveragePath = $ this ->getAbsolutePath ($ input ->getOption ('coverage ' ));
200+ $ output ->writeln ('<info>Generating code coverage reports on path: ' . $ coveragePath . '</info> ' );
227201
228202 foreach ($ this ->getPsr4Namespaces () as $ path ) {
229203 $ arguments [] = '--coverage-filter= ' . $ this ->getAbsolutePath ($ path );
230204 }
231205
232206 $ arguments [] = '--coverage-text ' ;
233- $ arguments [] = '--coverage-html= ' . $ this -> getAbsolutePath ( $ coverage ) ;
234- $ arguments [] = '--testdox-html= ' . $ this -> getAbsolutePath ( $ coverage ) . '/testdox.html ' ;
235- $ arguments [] = '--coverage-clover= ' . $ this -> getAbsolutePath ( $ coverage ) . '/clover.xml ' ;
236- $ arguments [] = '--coverage-php= ' . $ this -> getAbsolutePath ( $ coverage ) . '/coverage.php ' ;
207+ $ arguments [] = '--coverage-html= ' . $ coveragePath ;
208+ $ arguments [] = '--testdox-html= ' . $ coveragePath . '/testdox.html ' ;
209+ $ arguments [] = '--coverage-clover= ' . $ coveragePath . '/clover.xml ' ;
210+ $ arguments [] = '--coverage-php= ' . $ coveragePath . '/coverage.php ' ;
237211 }
238212
239- $ filter = $ input ->getOption ('filter ' );
240- if ($ filter !== null ) {
241- $ arguments [] = '--filter= ' . $ filter ;
213+ if (null !== $ input ->getOption ('filter ' )) {
214+ $ arguments [] = '--filter= ' . $ input ->getOption ('filter ' );
242215 }
243216
244217 $ arguments [] = $ input ->getArgument ('path ' ) ?? './tests ' ;
0 commit comments