Skip to content

Commit 218121b

Browse files
Closes #6346
1 parent 8543630 commit 218121b

23 files changed

Lines changed: 322 additions & 142 deletions

ChangeLog-13.2.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ All notable changes of the PHPUnit 13.2 release series are documented in this fi
1515
* [#5922](https://github.com/sebastianbergmann/phpunit/issues/5922): `assertContainsEquals()` should use `sebastian/comparator` for element comparison
1616
* [#6000](https://github.com/sebastianbergmann/phpunit/issues/6000): Report PHPT test as risky when `--SKIPIF--` does not have standard-output side-effect
1717
* [#6075](https://github.com/sebastianbergmann/phpunit/issues/6075): Support test execution order sorted by descending duration
18+
* [#6346](https://github.com/sebastianbergmann/phpunit/issues/6346): Emit warning when conflicting CLI options are used
1819
* [#6534](https://github.com/sebastianbergmann/phpunit/issues/6534): Make `$_dataName` available to `#[TestDoxFormatter]` callbacks
1920
* [#6559](https://github.com/sebastianbergmann/phpunit/issues/6559): Improved API for exception message expectations
2021
* [#6565](https://github.com/sebastianbergmann/phpunit/pull/6565): Optional `$skipWhenEmpty` parameter for `#[DataProvider]` and `#[DataProviderExternal]`

src/TextUI/Configuration/Cli/Builder.php

Lines changed: 79 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use const DIRECTORY_SEPARATOR;
1313
use function assert;
1414
use function basename;
15+
use function count;
1516
use function explode;
1617
use function getcwd;
1718
use 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
/**
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
todo
3+
--FILE--
4+
<?php declare(strict_types=1);
5+
$_SERVER['argv'][] = '--no-configuration';
6+
$_SERVER['argv'][] = '--debug';
7+
$_SERVER['argv'][] = '--cache-result';
8+
$_SERVER['argv'][] = '--do-not-cache-result';
9+
$_SERVER['argv'][] = __DIR__ . '/../../event/_files/SuccessTest.php';
10+
11+
require __DIR__ . '/../../../bootstrap.php';
12+
13+
(new PHPUnit\TextUI\Application)->run($_SERVER['argv']);
14+
--EXPECTF--
15+
%A
16+
Test Runner Triggered PHPUnit Warning (Options --cache-result and --do-not-cache-result cannot be used together)
17+
%A

0 commit comments

Comments
 (0)