1212use const DIRECTORY_SEPARATOR ;
1313use function assert ;
1414use function basename ;
15+ use function count ;
1516use function explode ;
1617use function getcwd ;
1718use function is_file ;
@@ -172,6 +173,51 @@ final class Builder
172173
173174 private const string SHORT_OPTIONS = 'd:c:h ' ;
174175
176+ /**
177+ * @var list<array{non-empty-string, non-empty-string}>
178+ */
179+ private const array CONFLICTING_OPTIONS = [
180+ ['--cache-result ' , '--do-not-cache-result ' ],
181+ ['--fail-on-deprecation ' , '--do-not-fail-on-deprecation ' ],
182+ ['--fail-on-phpunit-deprecation ' , '--do-not-fail-on-phpunit-deprecation ' ],
183+ ['--fail-on-phpunit-notice ' , '--do-not-fail-on-phpunit-notice ' ],
184+ ['--fail-on-phpunit-warning ' , '--do-not-fail-on-phpunit-warning ' ],
185+ ['--fail-on-empty-test-suite ' , '--do-not-fail-on-empty-test-suite ' ],
186+ ['--fail-on-incomplete ' , '--do-not-fail-on-incomplete ' ],
187+ ['--fail-on-notice ' , '--do-not-fail-on-notice ' ],
188+ ['--fail-on-risky ' , '--do-not-fail-on-risky ' ],
189+ ['--fail-on-skipped ' , '--do-not-fail-on-skipped ' ],
190+ ['--fail-on-warning ' , '--do-not-fail-on-warning ' ],
191+ ['--resolve-dependencies ' , '--ignore-dependencies ' ],
192+ ['--random-order ' , '--reverse-order ' ],
193+ ['--generate-baseline ' , '--ignore-baseline ' ],
194+ ['--generate-baseline ' , '--use-baseline ' ],
195+ ['--no-output ' , '--teamcity ' ],
196+ ['--no-output ' , '--testdox ' ],
197+ ['--no-output ' , '--testdox-summary ' ],
198+ ['--no-output ' , '--debug ' ],
199+ ];
200+
201+ /**
202+ * @var list<non-empty-string>
203+ */
204+ private const array COMMAND_OPTIONS = [
205+ '--atleast-version ' ,
206+ '--check-php-configuration ' ,
207+ '--check-version ' ,
208+ '--generate-configuration ' ,
209+ '--help ' ,
210+ '--list-groups ' ,
211+ '--list-suites ' ,
212+ '--list-test-files ' ,
213+ '--list-test-ids ' ,
214+ '--list-tests ' ,
215+ '--list-tests-xml ' ,
216+ '--migrate-configuration ' ,
217+ '--version ' ,
218+ '--warm-coverage-cache ' ,
219+ ];
220+
175221 /**
176222 * @var array<string, non-negative-int>
177223 */
@@ -767,221 +813,101 @@ public function fromParameters(array $parameters): Configuration
767813 break ;
768814
769815 case '--fail-on-deprecation ' :
770- $ this ->warnWhenOptionsConflict (
771- $ doNotFailOnDeprecation ,
772- '--fail-on-deprecation ' ,
773- '--do-not-fail-on-deprecation ' ,
774- );
775-
776816 $ failOnDeprecation = true ;
777817
778818 break ;
779819
780820 case '--fail-on-phpunit-deprecation ' :
781- $ this ->warnWhenOptionsConflict (
782- $ doNotFailOnPhpunitDeprecation ,
783- '--fail-on-phpunit-deprecation ' ,
784- '--do-not-fail-on-phpunit-deprecation ' ,
785- );
786-
787821 $ failOnPhpunitDeprecation = true ;
788822
789823 break ;
790824
791825 case '--fail-on-phpunit-notice ' :
792- $ this ->warnWhenOptionsConflict (
793- $ doNotFailOnPhpunitNotice ,
794- '--fail-on-phpunit-notice ' ,
795- '--do-not-fail-on-phpunit-notice ' ,
796- );
797-
798826 $ failOnPhpunitNotice = true ;
799827
800828 break ;
801829
802830 case '--fail-on-phpunit-warning ' :
803- $ this ->warnWhenOptionsConflict (
804- $ doNotFailOnPhpunitWarning ,
805- '--fail-on-phpunit-warning ' ,
806- '--do-not-fail-on-phpunit-warning ' ,
807- );
808-
809831 $ failOnPhpunitWarning = true ;
810832
811833 break ;
812834
813835 case '--fail-on-empty-test-suite ' :
814- $ this ->warnWhenOptionsConflict (
815- $ doNotFailOnEmptyTestSuite ,
816- '--fail-on-empty-test-suite ' ,
817- '--do-not-fail-on-empty-test-suite ' ,
818- );
819-
820836 $ failOnEmptyTestSuite = true ;
821837
822838 break ;
823839
824840 case '--fail-on-incomplete ' :
825- $ this ->warnWhenOptionsConflict (
826- $ doNotFailOnIncomplete ,
827- '--fail-on-incomplete ' ,
828- '--do-not-fail-on-incomplete ' ,
829- );
830-
831841 $ failOnIncomplete = true ;
832842
833843 break ;
834844
835845 case '--fail-on-notice ' :
836- $ this ->warnWhenOptionsConflict (
837- $ doNotFailOnNotice ,
838- '--fail-on-notice ' ,
839- '--do-not-fail-on-notice ' ,
840- );
841-
842846 $ failOnNotice = true ;
843847
844848 break ;
845849
846850 case '--fail-on-risky ' :
847- $ this ->warnWhenOptionsConflict (
848- $ doNotFailOnRisky ,
849- '--fail-on-risky ' ,
850- '--do-not-fail-on-risky ' ,
851- );
852-
853851 $ failOnRisky = true ;
854852
855853 break ;
856854
857855 case '--fail-on-skipped ' :
858- $ this ->warnWhenOptionsConflict (
859- $ doNotFailOnSkipped ,
860- '--fail-on-skipped ' ,
861- '--do-not-fail-on-skipped ' ,
862- );
863-
864856 $ failOnSkipped = true ;
865857
866858 break ;
867859
868860 case '--fail-on-warning ' :
869- $ this ->warnWhenOptionsConflict (
870- $ doNotFailOnWarning ,
871- '--fail-on-warning ' ,
872- '--do-not-fail-on-warning ' ,
873- );
874-
875861 $ failOnWarning = true ;
876862
877863 break ;
878864
879865 case '--do-not-fail-on-deprecation ' :
880- $ this ->warnWhenOptionsConflict (
881- $ failOnDeprecation ,
882- '--do-not-fail-on-deprecation ' ,
883- '--fail-on-deprecation ' ,
884- );
885-
886866 $ doNotFailOnDeprecation = true ;
887867
888868 break ;
889869
890870 case '--do-not-fail-on-phpunit-deprecation ' :
891- $ this ->warnWhenOptionsConflict (
892- $ failOnPhpunitDeprecation ,
893- '--do-not-fail-on-phpunit-deprecation ' ,
894- '--fail-on-phpunit-deprecation ' ,
895- );
896-
897871 $ doNotFailOnPhpunitDeprecation = true ;
898872
899873 break ;
900874
901875 case '--do-not-fail-on-phpunit-notice ' :
902- $ this ->warnWhenOptionsConflict (
903- $ failOnPhpunitNotice ,
904- '--do-not-fail-on-phpunit-notice ' ,
905- '--fail-on-phpunit-notice ' ,
906- );
907-
908876 $ doNotFailOnPhpunitNotice = true ;
909877
910878 break ;
911879
912880 case '--do-not-fail-on-phpunit-warning ' :
913- $ this ->warnWhenOptionsConflict (
914- $ failOnPhpunitWarning ,
915- '--do-not-fail-on-phpunit-warning ' ,
916- '--fail-on-phpunit-warning ' ,
917- );
918-
919881 $ doNotFailOnPhpunitWarning = true ;
920882
921883 break ;
922884
923885 case '--do-not-fail-on-empty-test-suite ' :
924- $ this ->warnWhenOptionsConflict (
925- $ failOnEmptyTestSuite ,
926- '--do-not-fail-on-empty-test-suite ' ,
927- '--fail-on-empty-test-suite ' ,
928- );
929-
930886 $ doNotFailOnEmptyTestSuite = true ;
931887
932888 break ;
933889
934890 case '--do-not-fail-on-incomplete ' :
935- $ this ->warnWhenOptionsConflict (
936- $ failOnIncomplete ,
937- '--do-not-fail-on-incomplete ' ,
938- '--fail-on-incomplete ' ,
939- );
940-
941891 $ doNotFailOnIncomplete = true ;
942892
943893 break ;
944894
945895 case '--do-not-fail-on-notice ' :
946- $ this ->warnWhenOptionsConflict (
947- $ failOnNotice ,
948- '--do-not-fail-on-notice ' ,
949- '--fail-on-notice ' ,
950- );
951-
952896 $ doNotFailOnNotice = true ;
953897
954898 break ;
955899
956900 case '--do-not-fail-on-risky ' :
957- $ this ->warnWhenOptionsConflict (
958- $ failOnRisky ,
959- '--do-not-fail-on-risky ' ,
960- '--fail-on-risky ' ,
961- );
962-
963901 $ doNotFailOnRisky = true ;
964902
965903 break ;
966904
967905 case '--do-not-fail-on-skipped ' :
968- $ this ->warnWhenOptionsConflict (
969- $ failOnSkipped ,
970- '--do-not-fail-on-skipped ' ,
971- '--fail-on-skipped ' ,
972- );
973-
974906 $ doNotFailOnSkipped = true ;
975907
976908 break ;
977909
978910 case '--do-not-fail-on-warning ' :
979- $ this ->warnWhenOptionsConflict (
980- $ failOnWarning ,
981- '--do-not-fail-on-warning ' ,
982- '--fail-on-warning ' ,
983- );
984-
985911 $ doNotFailOnWarning = true ;
986912
987913 break ;
@@ -1302,7 +1228,9 @@ public function fromParameters(array $parameters): Configuration
13021228 break ;
13031229 }
13041230
1305- if (!$ optionAllowedMultipleTimes ) {
1231+ if ($ optionAllowedMultipleTimes ) {
1232+ $ this ->processed [$ option [0 ]] = 1 ;
1233+ } else {
13061234 $ this ->markProcessed ($ option [0 ]);
13071235 }
13081236 }
@@ -1315,6 +1243,8 @@ public function fromParameters(array $parameters): Configuration
13151243 $ extensions = null ;
13161244 }
13171245
1246+ $ this ->warnAboutConflictingOptions ();
1247+
13181248 if ($ randomOrderSeed !== null && $ executionOrder !== TestSuiteSorter::ORDER_RANDOMIZED ) {
13191249 EventFacade::emitter ()->testRunnerTriggeredPhpunitWarning (
13201250 '--random-order-seed is only used when execution order is "random" (use --order-by random or --random-order) ' ,
@@ -1480,22 +1410,37 @@ private function markProcessed(string $option): void
14801410 }
14811411 }
14821412
1483- /**
1484- * @param non-empty-string $option
1485- */
1486- private function warnWhenOptionsConflict (?bool $ current , string $ option , string $ opposite ): void
1413+ private function warnAboutConflictingOptions (): void
14871414 {
1488- if ($ current === null ) {
1489- return ;
1415+ foreach (self ::CONFLICTING_OPTIONS as $ conflictingOptions ) {
1416+ if (isset ($ this ->processed [$ conflictingOptions [0 ]], $ this ->processed [$ conflictingOptions [1 ]])) {
1417+ EventFacade::emitter ()->testRunnerTriggeredPhpunitWarning (
1418+ sprintf (
1419+ 'Options %s and %s cannot be used together ' ,
1420+ $ conflictingOptions [0 ],
1421+ $ conflictingOptions [1 ],
1422+ ),
1423+ );
1424+ }
14901425 }
14911426
1492- EventFacade::emitter ()->testRunnerTriggeredPhpunitWarning (
1493- sprintf (
1494- 'Options %s and %s cannot be used together ' ,
1495- $ option ,
1496- $ opposite ,
1497- ),
1498- );
1427+ $ usedCommandOptions = [];
1428+
1429+ foreach (self ::COMMAND_OPTIONS as $ commandOption ) {
1430+ if (isset ($ this ->processed [$ commandOption ])) {
1431+ $ usedCommandOptions [] = $ commandOption ;
1432+ }
1433+ }
1434+
1435+ if (count ($ usedCommandOptions ) > 1 ) {
1436+ throw new Exception (
1437+ sprintf (
1438+ 'Options %s and %s cannot be used together ' ,
1439+ $ usedCommandOptions [0 ],
1440+ $ usedCommandOptions [1 ],
1441+ ),
1442+ );
1443+ }
14991444 }
15001445
15011446 /**
0 commit comments