Completed
Push — master ( 96d573...f9f049 )
by Ehsan
07:54
created

TestRunner::doRun()   F

Complexity

Conditions 87
Paths > 20000

Size

Total Lines 498
Code Lines 280

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 87
eloc 280
nc 4294967295
nop 3
dl 0
loc 498
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * This file is part of PHPUnit.
4
 *
5
 * (c) Sebastian Bergmann <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace PHPUnit\TextUI;
12
13
use PHPUnit\Framework\Error\Notice;
14
use PHPUnit\Framework\Error\Warning;
15
use PHPUnit\Framework\Exception;
16
use PHPUnit\Framework\TestSuite;
17
use PHPUnit\Framework\TestResult;
18
use PHPUnit\Framework\TestListener;
19
use PHPUnit\Framework\Test;
20
use PHPUnit\Runner\BaseTestRunner;
21
use PHPUnit\Runner\Filter\Factory;
22
use PHPUnit\Runner\Version;
23
use PHPUnit\Runner\TestSuiteLoader;
24
use PHPUnit\Runner\StandardTestSuiteLoader;
25
use PHPUnit\Runner\Filter\NameFilterIterator;
26
use PHPUnit\Runner\Filter\ExcludeGroupFilterIterator;
27
use PHPUnit\Runner\Filter\IncludeGroupFilterIterator;
28
use PHPUnit\Util\Configuration;
29
use PHPUnit\Util\Log\JUnit;
30
use PHPUnit\Util\Log\TeamCity;
31
use PHPUnit\Util\Printer;
32
use PHPUnit\Util\TestDox\HtmlResultPrinter;
33
use PHPUnit\Util\TestDox\TextResultPrinter;
34
use PHPUnit\Util\TestDox\XmlResultPrinter;
35
use ReflectionClass;
36
use SebastianBergmann;
37
use SebastianBergmann\CodeCoverage\CodeCoverage;
38
use SebastianBergmann\CodeCoverage\Exception as CodeCoverageException;
39
use SebastianBergmann\CodeCoverage\Filter as CodeCoverageFilter;
40
use SebastianBergmann\CodeCoverage\Report\Clover as CloverReport;
41
use SebastianBergmann\CodeCoverage\Report\Crap4j as Crap4jReport;
42
use SebastianBergmann\CodeCoverage\Report\Html\Facade as HtmlReport;
43
use SebastianBergmann\CodeCoverage\Report\PHP as PhpReport;
44
use SebastianBergmann\CodeCoverage\Report\Text as TextReport;
45
use SebastianBergmann\CodeCoverage\Report\Xml\Facade as XmlReport;
46
use SebastianBergmann\Environment\Runtime;
47
48
/**
49
 * A TestRunner for the Command Line Interface (CLI)
50
 * PHP SAPI Module.
51
 */
52
class TestRunner extends BaseTestRunner
53
{
54
    const SUCCESS_EXIT   = 0;
55
    const FAILURE_EXIT   = 1;
56
    const EXCEPTION_EXIT = 2;
57
58
    /**
59
     * @var CodeCoverageFilter
60
     */
61
    protected $codeCoverageFilter;
62
63
    /**
64
     * @var TestSuiteLoader
65
     */
66
    protected $loader;
67
68
    /**
69
     * @var ResultPrinter
70
     */
71
    protected $printer;
72
73
    /**
74
     * @var bool
75
     */
76
    protected static $versionStringPrinted = false;
77
78
    /**
79
     * @var Runtime
80
     */
81
    private $runtime;
82
83
    /**
84
     * @var bool
85
     */
86
    private $messagePrinted = false;
87
88
    /**
89
     * @param TestSuiteLoader    $loader
90
     * @param CodeCoverageFilter $filter
91
     */
92
    public function __construct(TestSuiteLoader $loader = null, CodeCoverageFilter $filter = null)
93
    {
94
        if ($filter === null) {
95
            $filter = new CodeCoverageFilter;
96
        }
97
98
        $this->codeCoverageFilter = $filter;
99
        $this->loader             = $loader;
100
        $this->runtime            = new Runtime;
101
    }
102
103
    /**
104
     * @param Test|ReflectionClass $test
105
     * @param array                $arguments
106
     *
107
     * @return TestResult
108
     *
109
     * @throws Exception
110
     */
111
    public static function run($test, array $arguments = [])
112
    {
113
        if ($test instanceof ReflectionClass) {
114
            $test = new TestSuite($test);
115
        }
116
117
        if ($test instanceof Test) {
118
            $aTestRunner = new self;
119
120
            return $aTestRunner->doRun(
121
                $test,
122
                $arguments
123
            );
124
        }
125
126
        throw new Exception('No test case or test suite found.');
127
    }
128
129
    /**
130
     * @return TestResult
131
     */
132
    protected function createTestResult()
133
    {
134
        return new TestResult;
135
    }
136
137
    /**
138
     * @param TestSuite $suite
139
     * @param array     $arguments
140
     */
141
    private function processSuiteFilters(TestSuite $suite, array $arguments)
142
    {
143
        if (!$arguments['filter'] &&
144
            empty($arguments['groups']) &&
145
            empty($arguments['excludeGroups'])) {
146
            return;
147
        }
148
149
        $filterFactory = new Factory;
150
151
        if (!empty($arguments['excludeGroups'])) {
152
            $filterFactory->addFilter(
153
                new ReflectionClass(ExcludeGroupFilterIterator::class),
154
                $arguments['excludeGroups']
155
            );
156
        }
157
158
        if (!empty($arguments['groups'])) {
159
            $filterFactory->addFilter(
160
                new ReflectionClass(IncludeGroupFilterIterator::class),
161
                $arguments['groups']
162
            );
163
        }
164
165
        if ($arguments['filter']) {
166
            $filterFactory->addFilter(
167
                new ReflectionClass(NameFilterIterator::class),
168
                $arguments['filter']
169
            );
170
        }
171
172
        $suite->injectFilter($filterFactory);
173
    }
174
175
    /**
176
     * @param Test  $suite
177
     * @param array $arguments
178
     * @param bool  $exit
179
     *
180
     * @return TestResult
181
     */
182
    public function doRun(Test $suite, array $arguments = [], $exit = true)
183
    {
184
        if (isset($arguments['configuration'])) {
185
            $GLOBALS['__PHPUNIT_CONFIGURATION_FILE'] = $arguments['configuration'];
186
        }
187
188
        $this->handleConfiguration($arguments);
189
190
        $this->processSuiteFilters($suite, $arguments);
0 ignored issues
show
Compatibility introduced by
$suite of type object<PHPUnit\Framework\Test> is not a sub-type of object<PHPUnit\Framework\TestSuite>. It seems like you assume a concrete implementation of the interface PHPUnit\Framework\Test to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
191
192
        if (isset($arguments['bootstrap'])) {
193
            $GLOBALS['__PHPUNIT_BOOTSTRAP'] = $arguments['bootstrap'];
194
        }
195
196
        if ($arguments['backupGlobals'] === true) {
197
            $suite->setBackupGlobals(true);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface PHPUnit\Framework\Test as the method setBackupGlobals() does only exist in the following implementations of said interface: AbstractTest, AbstractTest, AssertionExampleTest, AssertionExampleTest, BankAccountTest, BankAccountTest, BankAccountWithCustomExtensionTest, BankAccountWithCustomExtensionTest, BeforeAndAfterTest, BeforeAndAfterTest, BeforeClassAndAfterClassTest, BeforeClassAndAfterClassTest, BeforeClassWithOnlyDataProviderTest, BeforeClassWithOnlyDataProviderTest, ChangeCurrentWorkingDirectoryTest, ChangeCurrentWorkingDirectoryTest, ClonedDependencyTest, ClonedDependencyTest, ConcreteTest, ConcreteTest, ConcreteWithMyCustomExtensionTest, ConcreteWithMyCustomExtensionTest, CoverageClassExtendedTest, CoverageClassExtendedTest, CoverageClassTest, CoverageClassTest, CoverageFunctionParenthesesTest, CoverageFunctionParenthesesTest, CoverageFunctionParenthesesWhitespaceTest, CoverageFunctionParenthesesWhitespaceTest, CoverageFunctionTest, CoverageFunctionTest, CoverageMethodOneLineAnnotationTest, CoverageMethodOneLineAnnotationTest, CoverageMethodParenthesesTest, CoverageMethodParenthesesTest, CoverageMethodParenthesesWhitespaceTest, CoverageMethodParenthesesWhitespaceTest, CoverageMethodTest, CoverageMethodTest, CoverageNamespacedFunctionTest, CoverageNamespacedFunctionTest, CoverageNoneTest, CoverageNoneTest, CoverageNotPrivateTest, CoverageNotPrivateTest, CoverageNotProtectedTest, CoverageNotProtectedTest, CoverageNotPublicTest, CoverageNotPublicTest, CoverageNothingTest, CoverageNothingTest, CoveragePrivateTest, CoveragePrivateTest, CoverageProtectedTest, CoverageProtectedTest, CoveragePublicTest, CoveragePublicTest, DataProviderDebugTest, DataProviderDebugTest, DataProviderDependencyTest, DataProviderDependencyTest, DataProviderFilterTest, DataProviderFilterTest, DataProviderIncompleteTest, DataProviderIncompleteTest, DataProviderSkippedTest, DataProviderSkippedTest, DataProviderTest, DataProviderTest, DataProviderTestDoxTest, DataProviderTestDoxTest, DependencyFailureTest, DependencyFailureTest, DependencySuccessTest, DependencySuccessTest, DummyBarTest, DummyBarTest, DummyFooTest, DummyFooTest, EmptyTestCaseTest, EmptyTestCaseTest, ExceptionInAssertPostConditionsTest, ExceptionInAssertPostConditionsTest, ExceptionInAssertPreConditionsTest, ExceptionInAssertPreConditionsTest, ExceptionInSetUpTest, ExceptionInSetUpTest, ExceptionInTearDownTest, ExceptionInTearDownTest, ExceptionInTest, ExceptionInTest, ExceptionStackTest, ExceptionStackTest, ExceptionTest, ExceptionTest, Failure, Failure, FailureTest, FailureTest, FatalTest, FatalTest, Foo_Bar_Issue684Test, Foo_Bar_Issue684Test, Framework_MockBuilderTest, Framework_MockObjectTest, Framework_MockObject_Builder_InvocationMockerTest, Framework_MockObject_GeneratorTest, Framework_MockObject_Invocation_ObjectTest, Framework_MockObject_Invocation_StaticTest, Framework_MockObject_Mat...nsecutiveParametersTest, Framework_ProxyObjectTest, Humbug\Test\FunctionTest, Humbug\Test\FunctionTest, IgnoreCodeCoverageClassTest, IgnoreCodeCoverageClassTest, IncompleteTest, IncompleteTest, InheritanceA, InheritanceA, InheritanceB, InheritanceB, InheritedTestCase, InheritedTestCase, IniTest, IniTest, IsolationTest, IsolationTest, Issue1021Test, Issue1021Test, Issue1149Test, Issue1149Test, Issue1216Test, Issue1216Test, Issue1265Test, Issue1265Test, Issue1330Test, Issue1330Test, Issue1335Test, Issue1335Test, Issue1337Test, Issue1337Test, Issue1348Test, Issue1348Test, Issue1351Test, Issue1351Test, Issue1374Test, Issue1374Test, Issue1437Test, Issue1437Test, Issue1468Test, Issue1468Test, Issue1471Test, Issue1471Test, Issue1472Test, Issue1472Test, Issue1570Test, Issue1570Test, Issue2137Test, Issue2137Test, Issue2145Test, Issue2145Test, Issue2158Test, Issue2158Test, Issue2366Test, Issue2366Test, Issue2380Test, Issue2380Test, Issue2382Test, Issue2382Test, Issue2435Test, Issue2435Test, Issue244Test, Issue244Test, Issue322Test, Issue322Test, Issue433Test, Issue433Test, Issue445Test, Issue445Test, Issue498Test, Issue498Test, Issue503Test, Issue503Test, Issue523Test, Issue523Test, Issue578Test, Issue578Test, Issue581Test, Issue581Test, Issue74Test, Issue74Test, Issue765Test, Issue765Test, Issue797Test, Issue797Test, MultiDependencyTest, MultiDependencyTest, MultipleDataProviderTest, MultipleDataProviderTest, My\Space\ExceptionNamespaceTest, My\Space\ExceptionNamespaceTest, NamespaceCoverageClassExtendedTest, NamespaceCoverageClassExtendedTest, NamespaceCoverageClassTest, NamespaceCoverageClassTest, NamespaceCoverageCoversClassPublicTest, NamespaceCoverageCoversClassPublicTest, NamespaceCoverageCoversClassTest, NamespaceCoverageCoversClassTest, NamespaceCoverageMethodTest, NamespaceCoverageMethodTest, NamespaceCoverageNotPrivateTest, NamespaceCoverageNotPrivateTest, NamespaceCoverageNotProtectedTest, NamespaceCoverageNotProtectedTest, NamespaceCoverageNotPublicTest, NamespaceCoverageNotPublicTest, NamespaceCoveragePrivateTest, NamespaceCoveragePrivateTest, NamespaceCoverageProtectedTest, NamespaceCoverageProtectedTest, NamespaceCoveragePublicTest, NamespaceCoveragePublicTest, NoArgTestCaseTest, NoArgTestCaseTest, NoTestCases, NoTestCases, NotExistingCoveredElementTest, NotExistingCoveredElementTest, NotPublicTestCase, NotPublicTestCase, NotVoidTestCase, NotVoidTestCase, NothingTest, NothingTest, OneTest, OneTest, OneTestCase, OneTestCase, OutputTestCase, OutputTestCase, OverrideTestCase, OverrideTestCase, PHPUnit\Framework\AssertTest, PHPUnit\Framework\AssertTest, PHPUnit\Framework\BaseTestListenerTest, PHPUnit\Framework\BaseTestListenerTest, PHPUnit\Framework\ConstraintTest, PHPUnit\Framework\ConstraintTest, PHPUnit\Framework\Constraint\ArraySubsetTest, PHPUnit\Framework\Constraint\ArraySubsetTest, PHPUnit\Framework\Constraint\CountTest, PHPUnit\Framework\Constraint\CountTest, PHPUnit\Framework\Constr...eptionMessageRegExpTest, PHPUnit\Framework\Constr...eptionMessageRegExpTest, PHPUnit\Framework\Constraint\ExceptionMessageTest, PHPUnit\Framework\Constraint\ExceptionMessageTest, PHPUnit\Framework\Constraint\IsJsonTest, PHPUnit\Framework\Constraint\IsJsonTest, PHPUnit\Framework\Constr...rrorMessageProviderTest, PHPUnit\Framework\Constr...rrorMessageProviderTest, PHPUnit\Framework\Constraint\JsonMatchesTest, PHPUnit\Framework\Constraint\JsonMatchesTest, PHPUnit\Framework\DataProviderTestSuite, PHPUnit\Framework\DataProviderTestSuite, PHPUnit\Framework\IncompleteTestCase, PHPUnit\Framework\IncompleteTestCase, PHPUnit\Framework\SkippedTestCase, PHPUnit\Framework\SkippedTestCase, PHPUnit\Framework\SuiteTest, PHPUnit\Framework\SuiteTest, PHPUnit\Framework\TestCase, PHPUnit\Framework\TestCase, PHPUnit\Framework\TestCaseTest, PHPUnit\Framework\TestCaseTest, PHPUnit\Framework\TestFailureTest, PHPUnit\Framework\TestFailureTest, PHPUnit\Framework\TestImplementorTest, PHPUnit\Framework\TestImplementorTest, PHPUnit\Framework\TestListenerTest, PHPUnit\Framework\TestListenerTest, PHPUnit\Framework\TestSuite, PHPUnit\Framework\TestSuite, PHPUnit\Framework\WarningTestCase, PHPUnit\Framework\WarningTestCase, PHPUnit\Runner\PhptTestCaseTest, PHPUnit\Runner\PhptTestCaseTest, PHPUnit\Util\ConfigurationTest, PHPUnit\Util\ConfigurationTest, PHPUnit\Util\GetoptTest, PHPUnit\Util\GetoptTest, PHPUnit\Util\GlobalStateTest, PHPUnit\Util\GlobalStateTest, PHPUnit\Util\PHP\AbstractPhpProcessTest, PHPUnit\Util\PHP\AbstractPhpProcessTest, PHPUnit\Util\RegularExpressionTest, PHPUnit\Util\RegularExpressionTest, PHPUnit\Util\TestDox\NamePrettifierTest, PHPUnit\Util\TestDox\NamePrettifierTest, PHPUnit\Util\TestTest, PHPUnit\Util\TestTest, PHPUnit\Util\XmlTest, PHPUnit\Util\XmlTest, PHP_TimerTest, PharIo\Manifest\ApplicationNameTest, PharIo\Manifest\ApplicationTest, PharIo\Manifest\AuthorCollectionTest, PharIo\Manifest\AuthorTest, PharIo\Manifest\BundledComponentCollectionTest, PharIo\Manifest\BundledComponentTest, PharIo\Manifest\CopyrightInformationTest, PharIo\Manifest\EmailTest, PharIo\Manifest\ExtensionTest, PharIo\Manifest\LibraryTest, PharIo\Manifest\LicenseTest, PharIo\Manifest\ManifestTest, PharIo\Manifest\PhpExtensionRequirementTest, PharIo\Manifest\PhpVersionRequirementTest, PharIo\Manifest\RequirementCollectionTest, PharIo\Manifest\UrlTest, PharIo\Version\AbstractVersionConstraintTest, PharIo\Version\AndVersionConstraintGroupTest, PharIo\Version\AnyVersionConstraintTest, PharIo\Version\ExactVersionConstraintTest, PharIo\Version\GreaterTh...ToVersionConstraintTest, PharIo\Version\OrVersionConstraintGroupTest, PharIo\Version\SpecificM...orVersionConstraintTest, PharIo\Version\SpecificMajorVersionConstraintTest, PharIo\Version\VersionConstraintParserTest, PharIo\Version\VersionTest, RequirementsClassBeforeClassHookTest, RequirementsClassBeforeClassHookTest, RequirementsTest, RequirementsTest, SebastianBergmann\CodeCoverage\CodeCoverageTest, SebastianBergmann\CodeCoverage\FilterTest, SebastianBergmann\CodeCoverage\Report\BuilderTest, SebastianBergmann\CodeCoverage\Report\CloverTest, SebastianBergmann\CodeCoverage\Report\Crap4jTest, SebastianBergmann\CodeCo...ge\Report\Html\HTMLTest, SebastianBergmann\CodeCoverage\Report\TextTest, SebastianBergmann\CodeCoverage\Report\Xml\XMLTest, SebastianBergmann\CodeCoverage\TestCase, SebastianBergmann\CodeCoverage\UtilTest, SebastianBergmann\CodeUnitReverseLookup\WizardTest, SebastianBergmann\Comparator\ArrayComparatorTest, SebastianBergmann\Comparator\DOMNodeComparatorTest, SebastianBergmann\Compar...\DateTimeComparatorTest, SebastianBergmann\Comparator\DoubleComparatorTest, SebastianBergmann\Compar...ExceptionComparatorTest, SebastianBergmann\Comparator\FactoryTest, SebastianBergmann\Compar...ockObjectComparatorTest, SebastianBergmann\Comparator\NumericComparatorTest, SebastianBergmann\Comparator\ObjectComparatorTest, SebastianBergmann\Compar...\ResourceComparatorTest, SebastianBergmann\Comparator\ScalarComparatorTest, SebastianBergmann\Compar...ctStorageComparatorTest, SebastianBergmann\Comparator\TypeComparatorTest, SebastianBergmann\Diff\ChunkTest, SebastianBergmann\Diff\DiffTest, SebastianBergmann\Diff\DifferTest, SebastianBergmann\Diff\L...stCommonSubsequenceTest, SebastianBergmann\Diff\L...cientImplementationTest, SebastianBergmann\Diff\L...cientImplementationTest, SebastianBergmann\Diff\LineTest, SebastianBergmann\Diff\ParserTest, SebastianBergmann\Environment\ConsoleTest, SebastianBergmann\Environment\RuntimeTest, SebastianBergmann\Exporter\ExporterTest, SebastianBergmann\GlobalState\BlacklistTest, SebastianBergmann\GlobalState\CodeExporterTest, SebastianBergmann\GlobalState\RestorerTest, SebastianBergmann\GlobalState\SnapshotTest, SebastianBergmann\ObjectEnumerator\EnumeratorTest, SebastianBergmann\Object...tor\ObjectReflectorTest, SebastianBergmann\RecursionContext\ContextTest, StackTest, StackTest, StopsOnWarningTest, StopsOnWarningTest, Success, Success, Symfony\Component\Config...\ConfigCacheFactoryTest, Symfony\Component\Config\Tests\ConfigCacheTest, Symfony\Component\Config...efinition\ArrayNodeTest, Symfony\Component\Config...inition\BooleanNodeTest, Symfony\Component\Config...ArrayNodeDefinitionTest, Symfony\Component\Config...oleanNodeDefinitionTest, Symfony\Component\Config...\EnumNodeDefinitionTest, Symfony\Component\Config...Builder\ExprBuilderTest, Symfony\Component\Config...Builder\NodeBuilderTest, Symfony\Component\Config...mericNodeDefinitionTest, Symfony\Component\Config...Builder\TreeBuilderTest, Symfony\Component\Config...\XmlReferenceDumperTest, Symfony\Component\Config...YamlReferenceDumperTest, Symfony\Component\Config...Definition\EnumNodeTest, Symfony\Component\Config...nition\FinalizationTest, Symfony\Component\Config...efinition\FloatNodeTest, Symfony\Component\Config...inition\IntegerNodeTest, Symfony\Component\Config...ts\Definition\MergeTest, Symfony\Component\Config...ition\NormalizationTest, Symfony\Component\Config...PrototypedArrayNodeTest, Symfony\Component\Config...finition\ScalarNodeTest, Symfony\Component\Config...ion\ConfigCachePassTest, Symfony\Component\Config...LoaderLoadExceptionTest, Symfony\Component\Config\Tests\FileLocatorTest, Symfony\Component\Config...er\DelegatingLoaderTest, Symfony\Component\Config...s\Loader\FileLoaderTest, Symfony\Component\Config...ader\LoaderResolverTest, Symfony\Component\Config\Tests\Loader\LoaderTest, Symfony\Component\Config...eCheckerConfigCacheTest, Symfony\Component\Config...ssExistenceResourceTest, Symfony\Component\Config...ce\ComposerResourceTest, Symfony\Component\Config...e\DirectoryResourceTest, Symfony\Component\Config...leExistenceResourceTest, Symfony\Component\Config...source\FileResourceTest, Symfony\Component\Config...source\GlobResourceTest, Symfony\Component\Config...ectionClassResourceTest, Symfony\Component\Config\Tests\Util\XmlUtilsTest, Symfony\Component\Console\Tests\ApplicationTest, Symfony\Component\Consol...sts\Command\CommandTest, Symfony\Component\Consol...Command\HelpCommandTest, Symfony\Component\Consol...Command\ListCommandTest, Symfony\Component\Consol...mmand\LockableTraitTest, Symfony\Component\Consol...dConsoleCommandPassTest, Symfony\Component\Consol...\AbstractDescriptorTest, Symfony\Component\Consol...ptor\JsonDescriptorTest, Symfony\Component\Consol...\MarkdownDescriptorTest, Symfony\Component\Consol...ptor\TextDescriptorTest, Symfony\Component\Consol...iptor\XmlDescriptorTest, Symfony\Component\Consol...tener\ErrorListenerTest, Symfony\Component\Consol...FormatterStyleStackTest, Symfony\Component\Consol...utputFormatterStyleTest, Symfony\Component\Consol...ter\OutputFormatterTest, Symfony\Component\Consol...tractQuestionHelperTest, Symfony\Component\Consol...per\FormatterHelperTest, Symfony\Component\Consol...ts\Helper\HelperSetTest, Symfony\Component\Console\Tests\Helper\HelperTest, Symfony\Component\Consol...elper\ProcessHelperTest, Symfony\Component\Consol...\Helper\ProgressBarTest, Symfony\Component\Consol...r\ProgressIndicatorTest, Symfony\Component\Consol...lper\QuestionHelperTest, Symfony\Component\Consol...mfonyQuestionHelperTest, Symfony\Component\Consol...s\Helper\TableStyleTest, Symfony\Component\Console\Tests\Helper\TableTest, Symfony\Component\Consol...sts\Input\ArgvInputTest, Symfony\Component\Consol...ts\Input\ArrayInputTest, Symfony\Component\Consol...Input\InputArgumentTest, Symfony\Component\Consol...put\InputDefinitionTest, Symfony\Component\Consol...s\Input\InputOptionTest, Symfony\Component\Console\Tests\Input\InputTest, Symfony\Component\Consol...s\Input\StringInputTest, Symfony\Component\Consol...ogger\ConsoleLoggerTest, Symfony\Component\Consol...utput\ConsoleOutputTest, Symfony\Component\Consol...s\Output\NullOutputTest, Symfony\Component\Console\Tests\Output\OutputTest, Symfony\Component\Consol...Output\StreamOutputTest, Symfony\Component\Consol...\Style\SymfonyStyleTest, Symfony\Component\Console\Tests\TerminalTest, Symfony\Component\Consol...r\ApplicationTesterTest, Symfony\Component\Consol...ester\CommandTesterTest, Symfony\Component\Debug\Tests\DebugClassLoaderTest, Symfony\Component\Debug\Tests\ErrorHandlerTest, Symfony\Component\Debug\Tests\ExceptionHandlerTest, Symfony\Component\Debug\...on\FlattenExceptionTest, Symfony\Component\Debug\...ndFatalErrorHandlerTest, Symfony\Component\Debug\...onFatalErrorHandlerTest, Symfony\Component\Debug\...odFatalErrorHandlerTest, Symfony\Component\EventD...ractEventDispatcherTest, Symfony\Component\EventD...wareEventDispatcherTest, Symfony\Component\EventD...ableEventDispatcherTest, Symfony\Component\EventD...gisterListenersPassTest, Symfony\Component\EventD...sts\EventDispatcherTest, Symfony\Component\EventDispatcher\Tests\EventTest, Symfony\Component\EventD...\Tests\GenericEventTest, Symfony\Component\EventD...ableEventDispatcherTest, Symfony\Component\Filesystem\Tests\ExceptionTest, Symfony\Component\Filesystem\Tests\FilesystemTest, Symfony\Component\Filesy...ests\FilesystemTestCase, Symfony\Component\Filesystem\Tests\LockHandlerTest, Symfony\Component\Stopwa...ests\StopwatchEventTest, Symfony\Component\Stopwatch\Tests\StopwatchTest, Symfony\Component\Yaml\T...Command\LintCommandTest, Symfony\Component\Yaml\Tests\DumperTest, Symfony\Component\Yaml\Tests\InlineTest, Symfony\Component\Yaml\Tests\ParseExceptionTest, Symfony\Component\Yaml\Tests\ParserTest, Symfony\Component\Yaml\Tests\YamlTest, TemplateMethodsTest, TemplateMethodsTest, Test, TestAutoreferenced, TestAutoreferenced, TestDoxGroupTest, TestDoxGroupTest, TestError, TestError, TestIncomplete, TestIncomplete, TestSkipped, TestSkipped, TestWithTest, TestWithTest, TheSeer\Tokenizer\NamespaceUriTest, TheSeer\Tokenizer\TokenCollectionTest, TheSeer\Tokenizer\TokenTest, TheSeer\Tokenizer\TokenizerTest, TheSeer\Tokenizer\XMLSerializerTest, ThrowExceptionTestCase, ThrowExceptionTestCase, ThrowNoExceptionTestCase, ThrowNoExceptionTestCase, TwoTest, TwoTest, WasRun, WasRun, vendor\project\StatusTest, vendor\project\StatusTest.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
198
        }
199
200
        if ($arguments['backupStaticAttributes'] === true) {
201
            $suite->setBackupStaticAttributes(true);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface PHPUnit\Framework\Test as the method setBackupStaticAttributes() does only exist in the following implementations of said interface: AbstractTest, AbstractTest, AssertionExampleTest, AssertionExampleTest, BankAccountTest, BankAccountTest, BankAccountWithCustomExtensionTest, BankAccountWithCustomExtensionTest, BeforeAndAfterTest, BeforeAndAfterTest, BeforeClassAndAfterClassTest, BeforeClassAndAfterClassTest, BeforeClassWithOnlyDataProviderTest, BeforeClassWithOnlyDataProviderTest, ChangeCurrentWorkingDirectoryTest, ChangeCurrentWorkingDirectoryTest, ClonedDependencyTest, ClonedDependencyTest, ConcreteTest, ConcreteTest, ConcreteWithMyCustomExtensionTest, ConcreteWithMyCustomExtensionTest, CoverageClassExtendedTest, CoverageClassExtendedTest, CoverageClassTest, CoverageClassTest, CoverageFunctionParenthesesTest, CoverageFunctionParenthesesTest, CoverageFunctionParenthesesWhitespaceTest, CoverageFunctionParenthesesWhitespaceTest, CoverageFunctionTest, CoverageFunctionTest, CoverageMethodOneLineAnnotationTest, CoverageMethodOneLineAnnotationTest, CoverageMethodParenthesesTest, CoverageMethodParenthesesTest, CoverageMethodParenthesesWhitespaceTest, CoverageMethodParenthesesWhitespaceTest, CoverageMethodTest, CoverageMethodTest, CoverageNamespacedFunctionTest, CoverageNamespacedFunctionTest, CoverageNoneTest, CoverageNoneTest, CoverageNotPrivateTest, CoverageNotPrivateTest, CoverageNotProtectedTest, CoverageNotProtectedTest, CoverageNotPublicTest, CoverageNotPublicTest, CoverageNothingTest, CoverageNothingTest, CoveragePrivateTest, CoveragePrivateTest, CoverageProtectedTest, CoverageProtectedTest, CoveragePublicTest, CoveragePublicTest, DataProviderDebugTest, DataProviderDebugTest, DataProviderDependencyTest, DataProviderDependencyTest, DataProviderFilterTest, DataProviderFilterTest, DataProviderIncompleteTest, DataProviderIncompleteTest, DataProviderSkippedTest, DataProviderSkippedTest, DataProviderTest, DataProviderTest, DataProviderTestDoxTest, DataProviderTestDoxTest, DependencyFailureTest, DependencyFailureTest, DependencySuccessTest, DependencySuccessTest, DummyBarTest, DummyBarTest, DummyFooTest, DummyFooTest, EmptyTestCaseTest, EmptyTestCaseTest, ExceptionInAssertPostConditionsTest, ExceptionInAssertPostConditionsTest, ExceptionInAssertPreConditionsTest, ExceptionInAssertPreConditionsTest, ExceptionInSetUpTest, ExceptionInSetUpTest, ExceptionInTearDownTest, ExceptionInTearDownTest, ExceptionInTest, ExceptionInTest, ExceptionStackTest, ExceptionStackTest, ExceptionTest, ExceptionTest, Failure, Failure, FailureTest, FailureTest, FatalTest, FatalTest, Foo_Bar_Issue684Test, Foo_Bar_Issue684Test, Framework_MockBuilderTest, Framework_MockObjectTest, Framework_MockObject_Builder_InvocationMockerTest, Framework_MockObject_GeneratorTest, Framework_MockObject_Invocation_ObjectTest, Framework_MockObject_Invocation_StaticTest, Framework_MockObject_Mat...nsecutiveParametersTest, Framework_ProxyObjectTest, Humbug\Test\FunctionTest, Humbug\Test\FunctionTest, IgnoreCodeCoverageClassTest, IgnoreCodeCoverageClassTest, IncompleteTest, IncompleteTest, InheritanceA, InheritanceA, InheritanceB, InheritanceB, InheritedTestCase, InheritedTestCase, IniTest, IniTest, IsolationTest, IsolationTest, Issue1021Test, Issue1021Test, Issue1149Test, Issue1149Test, Issue1216Test, Issue1216Test, Issue1265Test, Issue1265Test, Issue1330Test, Issue1330Test, Issue1335Test, Issue1335Test, Issue1337Test, Issue1337Test, Issue1348Test, Issue1348Test, Issue1351Test, Issue1351Test, Issue1374Test, Issue1374Test, Issue1437Test, Issue1437Test, Issue1468Test, Issue1468Test, Issue1471Test, Issue1471Test, Issue1472Test, Issue1472Test, Issue1570Test, Issue1570Test, Issue2137Test, Issue2137Test, Issue2145Test, Issue2145Test, Issue2158Test, Issue2158Test, Issue2366Test, Issue2366Test, Issue2380Test, Issue2380Test, Issue2382Test, Issue2382Test, Issue2435Test, Issue2435Test, Issue244Test, Issue244Test, Issue322Test, Issue322Test, Issue433Test, Issue433Test, Issue445Test, Issue445Test, Issue498Test, Issue498Test, Issue503Test, Issue503Test, Issue523Test, Issue523Test, Issue578Test, Issue578Test, Issue581Test, Issue581Test, Issue74Test, Issue74Test, Issue765Test, Issue765Test, Issue797Test, Issue797Test, MultiDependencyTest, MultiDependencyTest, MultipleDataProviderTest, MultipleDataProviderTest, My\Space\ExceptionNamespaceTest, My\Space\ExceptionNamespaceTest, NamespaceCoverageClassExtendedTest, NamespaceCoverageClassExtendedTest, NamespaceCoverageClassTest, NamespaceCoverageClassTest, NamespaceCoverageCoversClassPublicTest, NamespaceCoverageCoversClassPublicTest, NamespaceCoverageCoversClassTest, NamespaceCoverageCoversClassTest, NamespaceCoverageMethodTest, NamespaceCoverageMethodTest, NamespaceCoverageNotPrivateTest, NamespaceCoverageNotPrivateTest, NamespaceCoverageNotProtectedTest, NamespaceCoverageNotProtectedTest, NamespaceCoverageNotPublicTest, NamespaceCoverageNotPublicTest, NamespaceCoveragePrivateTest, NamespaceCoveragePrivateTest, NamespaceCoverageProtectedTest, NamespaceCoverageProtectedTest, NamespaceCoveragePublicTest, NamespaceCoveragePublicTest, NoArgTestCaseTest, NoArgTestCaseTest, NoTestCases, NoTestCases, NotExistingCoveredElementTest, NotExistingCoveredElementTest, NotPublicTestCase, NotPublicTestCase, NotVoidTestCase, NotVoidTestCase, NothingTest, NothingTest, OneTest, OneTest, OneTestCase, OneTestCase, OutputTestCase, OutputTestCase, OverrideTestCase, OverrideTestCase, PHPUnit\Framework\AssertTest, PHPUnit\Framework\AssertTest, PHPUnit\Framework\BaseTestListenerTest, PHPUnit\Framework\BaseTestListenerTest, PHPUnit\Framework\ConstraintTest, PHPUnit\Framework\ConstraintTest, PHPUnit\Framework\Constraint\ArraySubsetTest, PHPUnit\Framework\Constraint\ArraySubsetTest, PHPUnit\Framework\Constraint\CountTest, PHPUnit\Framework\Constraint\CountTest, PHPUnit\Framework\Constr...eptionMessageRegExpTest, PHPUnit\Framework\Constr...eptionMessageRegExpTest, PHPUnit\Framework\Constraint\ExceptionMessageTest, PHPUnit\Framework\Constraint\ExceptionMessageTest, PHPUnit\Framework\Constraint\IsJsonTest, PHPUnit\Framework\Constraint\IsJsonTest, PHPUnit\Framework\Constr...rrorMessageProviderTest, PHPUnit\Framework\Constr...rrorMessageProviderTest, PHPUnit\Framework\Constraint\JsonMatchesTest, PHPUnit\Framework\Constraint\JsonMatchesTest, PHPUnit\Framework\DataProviderTestSuite, PHPUnit\Framework\DataProviderTestSuite, PHPUnit\Framework\IncompleteTestCase, PHPUnit\Framework\IncompleteTestCase, PHPUnit\Framework\SkippedTestCase, PHPUnit\Framework\SkippedTestCase, PHPUnit\Framework\SuiteTest, PHPUnit\Framework\SuiteTest, PHPUnit\Framework\TestCase, PHPUnit\Framework\TestCase, PHPUnit\Framework\TestCaseTest, PHPUnit\Framework\TestCaseTest, PHPUnit\Framework\TestFailureTest, PHPUnit\Framework\TestFailureTest, PHPUnit\Framework\TestImplementorTest, PHPUnit\Framework\TestImplementorTest, PHPUnit\Framework\TestListenerTest, PHPUnit\Framework\TestListenerTest, PHPUnit\Framework\TestSuite, PHPUnit\Framework\TestSuite, PHPUnit\Framework\WarningTestCase, PHPUnit\Framework\WarningTestCase, PHPUnit\Runner\PhptTestCaseTest, PHPUnit\Runner\PhptTestCaseTest, PHPUnit\Util\ConfigurationTest, PHPUnit\Util\ConfigurationTest, PHPUnit\Util\GetoptTest, PHPUnit\Util\GetoptTest, PHPUnit\Util\GlobalStateTest, PHPUnit\Util\GlobalStateTest, PHPUnit\Util\PHP\AbstractPhpProcessTest, PHPUnit\Util\PHP\AbstractPhpProcessTest, PHPUnit\Util\RegularExpressionTest, PHPUnit\Util\RegularExpressionTest, PHPUnit\Util\TestDox\NamePrettifierTest, PHPUnit\Util\TestDox\NamePrettifierTest, PHPUnit\Util\TestTest, PHPUnit\Util\TestTest, PHPUnit\Util\XmlTest, PHPUnit\Util\XmlTest, PHP_TimerTest, PharIo\Manifest\ApplicationNameTest, PharIo\Manifest\ApplicationTest, PharIo\Manifest\AuthorCollectionTest, PharIo\Manifest\AuthorTest, PharIo\Manifest\BundledComponentCollectionTest, PharIo\Manifest\BundledComponentTest, PharIo\Manifest\CopyrightInformationTest, PharIo\Manifest\EmailTest, PharIo\Manifest\ExtensionTest, PharIo\Manifest\LibraryTest, PharIo\Manifest\LicenseTest, PharIo\Manifest\ManifestTest, PharIo\Manifest\PhpExtensionRequirementTest, PharIo\Manifest\PhpVersionRequirementTest, PharIo\Manifest\RequirementCollectionTest, PharIo\Manifest\UrlTest, PharIo\Version\AbstractVersionConstraintTest, PharIo\Version\AndVersionConstraintGroupTest, PharIo\Version\AnyVersionConstraintTest, PharIo\Version\ExactVersionConstraintTest, PharIo\Version\GreaterTh...ToVersionConstraintTest, PharIo\Version\OrVersionConstraintGroupTest, PharIo\Version\SpecificM...orVersionConstraintTest, PharIo\Version\SpecificMajorVersionConstraintTest, PharIo\Version\VersionConstraintParserTest, PharIo\Version\VersionTest, RequirementsClassBeforeClassHookTest, RequirementsClassBeforeClassHookTest, RequirementsTest, RequirementsTest, SebastianBergmann\CodeCoverage\CodeCoverageTest, SebastianBergmann\CodeCoverage\FilterTest, SebastianBergmann\CodeCoverage\Report\BuilderTest, SebastianBergmann\CodeCoverage\Report\CloverTest, SebastianBergmann\CodeCoverage\Report\Crap4jTest, SebastianBergmann\CodeCo...ge\Report\Html\HTMLTest, SebastianBergmann\CodeCoverage\Report\TextTest, SebastianBergmann\CodeCoverage\Report\Xml\XMLTest, SebastianBergmann\CodeCoverage\TestCase, SebastianBergmann\CodeCoverage\UtilTest, SebastianBergmann\CodeUnitReverseLookup\WizardTest, SebastianBergmann\Comparator\ArrayComparatorTest, SebastianBergmann\Comparator\DOMNodeComparatorTest, SebastianBergmann\Compar...\DateTimeComparatorTest, SebastianBergmann\Comparator\DoubleComparatorTest, SebastianBergmann\Compar...ExceptionComparatorTest, SebastianBergmann\Comparator\FactoryTest, SebastianBergmann\Compar...ockObjectComparatorTest, SebastianBergmann\Comparator\NumericComparatorTest, SebastianBergmann\Comparator\ObjectComparatorTest, SebastianBergmann\Compar...\ResourceComparatorTest, SebastianBergmann\Comparator\ScalarComparatorTest, SebastianBergmann\Compar...ctStorageComparatorTest, SebastianBergmann\Comparator\TypeComparatorTest, SebastianBergmann\Diff\ChunkTest, SebastianBergmann\Diff\DiffTest, SebastianBergmann\Diff\DifferTest, SebastianBergmann\Diff\L...stCommonSubsequenceTest, SebastianBergmann\Diff\L...cientImplementationTest, SebastianBergmann\Diff\L...cientImplementationTest, SebastianBergmann\Diff\LineTest, SebastianBergmann\Diff\ParserTest, SebastianBergmann\Environment\ConsoleTest, SebastianBergmann\Environment\RuntimeTest, SebastianBergmann\Exporter\ExporterTest, SebastianBergmann\GlobalState\BlacklistTest, SebastianBergmann\GlobalState\CodeExporterTest, SebastianBergmann\GlobalState\RestorerTest, SebastianBergmann\GlobalState\SnapshotTest, SebastianBergmann\ObjectEnumerator\EnumeratorTest, SebastianBergmann\Object...tor\ObjectReflectorTest, SebastianBergmann\RecursionContext\ContextTest, StackTest, StackTest, StopsOnWarningTest, StopsOnWarningTest, Success, Success, Symfony\Component\Config...\ConfigCacheFactoryTest, Symfony\Component\Config\Tests\ConfigCacheTest, Symfony\Component\Config...efinition\ArrayNodeTest, Symfony\Component\Config...inition\BooleanNodeTest, Symfony\Component\Config...ArrayNodeDefinitionTest, Symfony\Component\Config...oleanNodeDefinitionTest, Symfony\Component\Config...\EnumNodeDefinitionTest, Symfony\Component\Config...Builder\ExprBuilderTest, Symfony\Component\Config...Builder\NodeBuilderTest, Symfony\Component\Config...mericNodeDefinitionTest, Symfony\Component\Config...Builder\TreeBuilderTest, Symfony\Component\Config...\XmlReferenceDumperTest, Symfony\Component\Config...YamlReferenceDumperTest, Symfony\Component\Config...Definition\EnumNodeTest, Symfony\Component\Config...nition\FinalizationTest, Symfony\Component\Config...efinition\FloatNodeTest, Symfony\Component\Config...inition\IntegerNodeTest, Symfony\Component\Config...ts\Definition\MergeTest, Symfony\Component\Config...ition\NormalizationTest, Symfony\Component\Config...PrototypedArrayNodeTest, Symfony\Component\Config...finition\ScalarNodeTest, Symfony\Component\Config...ion\ConfigCachePassTest, Symfony\Component\Config...LoaderLoadExceptionTest, Symfony\Component\Config\Tests\FileLocatorTest, Symfony\Component\Config...er\DelegatingLoaderTest, Symfony\Component\Config...s\Loader\FileLoaderTest, Symfony\Component\Config...ader\LoaderResolverTest, Symfony\Component\Config\Tests\Loader\LoaderTest, Symfony\Component\Config...eCheckerConfigCacheTest, Symfony\Component\Config...ssExistenceResourceTest, Symfony\Component\Config...ce\ComposerResourceTest, Symfony\Component\Config...e\DirectoryResourceTest, Symfony\Component\Config...leExistenceResourceTest, Symfony\Component\Config...source\FileResourceTest, Symfony\Component\Config...source\GlobResourceTest, Symfony\Component\Config...ectionClassResourceTest, Symfony\Component\Config\Tests\Util\XmlUtilsTest, Symfony\Component\Console\Tests\ApplicationTest, Symfony\Component\Consol...sts\Command\CommandTest, Symfony\Component\Consol...Command\HelpCommandTest, Symfony\Component\Consol...Command\ListCommandTest, Symfony\Component\Consol...mmand\LockableTraitTest, Symfony\Component\Consol...dConsoleCommandPassTest, Symfony\Component\Consol...\AbstractDescriptorTest, Symfony\Component\Consol...ptor\JsonDescriptorTest, Symfony\Component\Consol...\MarkdownDescriptorTest, Symfony\Component\Consol...ptor\TextDescriptorTest, Symfony\Component\Consol...iptor\XmlDescriptorTest, Symfony\Component\Consol...tener\ErrorListenerTest, Symfony\Component\Consol...FormatterStyleStackTest, Symfony\Component\Consol...utputFormatterStyleTest, Symfony\Component\Consol...ter\OutputFormatterTest, Symfony\Component\Consol...tractQuestionHelperTest, Symfony\Component\Consol...per\FormatterHelperTest, Symfony\Component\Consol...ts\Helper\HelperSetTest, Symfony\Component\Console\Tests\Helper\HelperTest, Symfony\Component\Consol...elper\ProcessHelperTest, Symfony\Component\Consol...\Helper\ProgressBarTest, Symfony\Component\Consol...r\ProgressIndicatorTest, Symfony\Component\Consol...lper\QuestionHelperTest, Symfony\Component\Consol...mfonyQuestionHelperTest, Symfony\Component\Consol...s\Helper\TableStyleTest, Symfony\Component\Console\Tests\Helper\TableTest, Symfony\Component\Consol...sts\Input\ArgvInputTest, Symfony\Component\Consol...ts\Input\ArrayInputTest, Symfony\Component\Consol...Input\InputArgumentTest, Symfony\Component\Consol...put\InputDefinitionTest, Symfony\Component\Consol...s\Input\InputOptionTest, Symfony\Component\Console\Tests\Input\InputTest, Symfony\Component\Consol...s\Input\StringInputTest, Symfony\Component\Consol...ogger\ConsoleLoggerTest, Symfony\Component\Consol...utput\ConsoleOutputTest, Symfony\Component\Consol...s\Output\NullOutputTest, Symfony\Component\Console\Tests\Output\OutputTest, Symfony\Component\Consol...Output\StreamOutputTest, Symfony\Component\Consol...\Style\SymfonyStyleTest, Symfony\Component\Console\Tests\TerminalTest, Symfony\Component\Consol...r\ApplicationTesterTest, Symfony\Component\Consol...ester\CommandTesterTest, Symfony\Component\Debug\Tests\DebugClassLoaderTest, Symfony\Component\Debug\Tests\ErrorHandlerTest, Symfony\Component\Debug\Tests\ExceptionHandlerTest, Symfony\Component\Debug\...on\FlattenExceptionTest, Symfony\Component\Debug\...ndFatalErrorHandlerTest, Symfony\Component\Debug\...onFatalErrorHandlerTest, Symfony\Component\Debug\...odFatalErrorHandlerTest, Symfony\Component\EventD...ractEventDispatcherTest, Symfony\Component\EventD...wareEventDispatcherTest, Symfony\Component\EventD...ableEventDispatcherTest, Symfony\Component\EventD...gisterListenersPassTest, Symfony\Component\EventD...sts\EventDispatcherTest, Symfony\Component\EventDispatcher\Tests\EventTest, Symfony\Component\EventD...\Tests\GenericEventTest, Symfony\Component\EventD...ableEventDispatcherTest, Symfony\Component\Filesystem\Tests\ExceptionTest, Symfony\Component\Filesystem\Tests\FilesystemTest, Symfony\Component\Filesy...ests\FilesystemTestCase, Symfony\Component\Filesystem\Tests\LockHandlerTest, Symfony\Component\Stopwa...ests\StopwatchEventTest, Symfony\Component\Stopwatch\Tests\StopwatchTest, Symfony\Component\Yaml\T...Command\LintCommandTest, Symfony\Component\Yaml\Tests\DumperTest, Symfony\Component\Yaml\Tests\InlineTest, Symfony\Component\Yaml\Tests\ParseExceptionTest, Symfony\Component\Yaml\Tests\ParserTest, Symfony\Component\Yaml\Tests\YamlTest, TemplateMethodsTest, TemplateMethodsTest, Test, TestAutoreferenced, TestAutoreferenced, TestDoxGroupTest, TestDoxGroupTest, TestError, TestError, TestIncomplete, TestIncomplete, TestSkipped, TestSkipped, TestWithTest, TestWithTest, TheSeer\Tokenizer\NamespaceUriTest, TheSeer\Tokenizer\TokenCollectionTest, TheSeer\Tokenizer\TokenTest, TheSeer\Tokenizer\TokenizerTest, TheSeer\Tokenizer\XMLSerializerTest, ThrowExceptionTestCase, ThrowExceptionTestCase, ThrowNoExceptionTestCase, ThrowNoExceptionTestCase, TwoTest, TwoTest, WasRun, WasRun, vendor\project\StatusTest, vendor\project\StatusTest.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
202
        }
203
204
        if ($arguments['beStrictAboutChangesToGlobalState'] === true) {
205
            $suite->setbeStrictAboutChangesToGlobalState(true);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface PHPUnit\Framework\Test as the method setbeStrictAboutChangesToGlobalState() does only exist in the following implementations of said interface: AbstractTest, AbstractTest, AssertionExampleTest, AssertionExampleTest, BankAccountTest, BankAccountTest, BankAccountWithCustomExtensionTest, BankAccountWithCustomExtensionTest, BeforeAndAfterTest, BeforeAndAfterTest, BeforeClassAndAfterClassTest, BeforeClassAndAfterClassTest, BeforeClassWithOnlyDataProviderTest, BeforeClassWithOnlyDataProviderTest, ChangeCurrentWorkingDirectoryTest, ChangeCurrentWorkingDirectoryTest, ClonedDependencyTest, ClonedDependencyTest, ConcreteTest, ConcreteTest, ConcreteWithMyCustomExtensionTest, ConcreteWithMyCustomExtensionTest, CoverageClassExtendedTest, CoverageClassExtendedTest, CoverageClassTest, CoverageClassTest, CoverageFunctionParenthesesTest, CoverageFunctionParenthesesTest, CoverageFunctionParenthesesWhitespaceTest, CoverageFunctionParenthesesWhitespaceTest, CoverageFunctionTest, CoverageFunctionTest, CoverageMethodOneLineAnnotationTest, CoverageMethodOneLineAnnotationTest, CoverageMethodParenthesesTest, CoverageMethodParenthesesTest, CoverageMethodParenthesesWhitespaceTest, CoverageMethodParenthesesWhitespaceTest, CoverageMethodTest, CoverageMethodTest, CoverageNamespacedFunctionTest, CoverageNamespacedFunctionTest, CoverageNoneTest, CoverageNoneTest, CoverageNotPrivateTest, CoverageNotPrivateTest, CoverageNotProtectedTest, CoverageNotProtectedTest, CoverageNotPublicTest, CoverageNotPublicTest, CoverageNothingTest, CoverageNothingTest, CoveragePrivateTest, CoveragePrivateTest, CoverageProtectedTest, CoverageProtectedTest, CoveragePublicTest, CoveragePublicTest, DataProviderDebugTest, DataProviderDebugTest, DataProviderDependencyTest, DataProviderDependencyTest, DataProviderFilterTest, DataProviderFilterTest, DataProviderIncompleteTest, DataProviderIncompleteTest, DataProviderSkippedTest, DataProviderSkippedTest, DataProviderTest, DataProviderTest, DataProviderTestDoxTest, DataProviderTestDoxTest, DependencyFailureTest, DependencyFailureTest, DependencySuccessTest, DependencySuccessTest, DummyBarTest, DummyBarTest, DummyFooTest, DummyFooTest, EmptyTestCaseTest, EmptyTestCaseTest, ExceptionInAssertPostConditionsTest, ExceptionInAssertPostConditionsTest, ExceptionInAssertPreConditionsTest, ExceptionInAssertPreConditionsTest, ExceptionInSetUpTest, ExceptionInSetUpTest, ExceptionInTearDownTest, ExceptionInTearDownTest, ExceptionInTest, ExceptionInTest, ExceptionStackTest, ExceptionStackTest, ExceptionTest, ExceptionTest, Failure, Failure, FailureTest, FailureTest, FatalTest, FatalTest, Foo_Bar_Issue684Test, Foo_Bar_Issue684Test, Framework_MockBuilderTest, Framework_MockObjectTest, Framework_MockObject_Builder_InvocationMockerTest, Framework_MockObject_GeneratorTest, Framework_MockObject_Invocation_ObjectTest, Framework_MockObject_Invocation_StaticTest, Framework_MockObject_Mat...nsecutiveParametersTest, Framework_ProxyObjectTest, Humbug\Test\FunctionTest, Humbug\Test\FunctionTest, IgnoreCodeCoverageClassTest, IgnoreCodeCoverageClassTest, IncompleteTest, IncompleteTest, InheritanceA, InheritanceA, InheritanceB, InheritanceB, InheritedTestCase, InheritedTestCase, IniTest, IniTest, IsolationTest, IsolationTest, Issue1021Test, Issue1021Test, Issue1149Test, Issue1149Test, Issue1216Test, Issue1216Test, Issue1265Test, Issue1265Test, Issue1330Test, Issue1330Test, Issue1335Test, Issue1335Test, Issue1337Test, Issue1337Test, Issue1348Test, Issue1348Test, Issue1351Test, Issue1351Test, Issue1374Test, Issue1374Test, Issue1437Test, Issue1437Test, Issue1468Test, Issue1468Test, Issue1471Test, Issue1471Test, Issue1472Test, Issue1472Test, Issue1570Test, Issue1570Test, Issue2137Test, Issue2137Test, Issue2145Test, Issue2145Test, Issue2158Test, Issue2158Test, Issue2366Test, Issue2366Test, Issue2380Test, Issue2380Test, Issue2382Test, Issue2382Test, Issue2435Test, Issue2435Test, Issue244Test, Issue244Test, Issue322Test, Issue322Test, Issue433Test, Issue433Test, Issue445Test, Issue445Test, Issue498Test, Issue498Test, Issue503Test, Issue503Test, Issue523Test, Issue523Test, Issue578Test, Issue578Test, Issue581Test, Issue581Test, Issue74Test, Issue74Test, Issue765Test, Issue765Test, Issue797Test, Issue797Test, MultiDependencyTest, MultiDependencyTest, MultipleDataProviderTest, MultipleDataProviderTest, My\Space\ExceptionNamespaceTest, My\Space\ExceptionNamespaceTest, NamespaceCoverageClassExtendedTest, NamespaceCoverageClassExtendedTest, NamespaceCoverageClassTest, NamespaceCoverageClassTest, NamespaceCoverageCoversClassPublicTest, NamespaceCoverageCoversClassPublicTest, NamespaceCoverageCoversClassTest, NamespaceCoverageCoversClassTest, NamespaceCoverageMethodTest, NamespaceCoverageMethodTest, NamespaceCoverageNotPrivateTest, NamespaceCoverageNotPrivateTest, NamespaceCoverageNotProtectedTest, NamespaceCoverageNotProtectedTest, NamespaceCoverageNotPublicTest, NamespaceCoverageNotPublicTest, NamespaceCoveragePrivateTest, NamespaceCoveragePrivateTest, NamespaceCoverageProtectedTest, NamespaceCoverageProtectedTest, NamespaceCoveragePublicTest, NamespaceCoveragePublicTest, NoArgTestCaseTest, NoArgTestCaseTest, NoTestCases, NoTestCases, NotExistingCoveredElementTest, NotExistingCoveredElementTest, NotPublicTestCase, NotPublicTestCase, NotVoidTestCase, NotVoidTestCase, NothingTest, NothingTest, OneTest, OneTest, OneTestCase, OneTestCase, OutputTestCase, OutputTestCase, OverrideTestCase, OverrideTestCase, PHPUnit\Framework\AssertTest, PHPUnit\Framework\AssertTest, PHPUnit\Framework\BaseTestListenerTest, PHPUnit\Framework\BaseTestListenerTest, PHPUnit\Framework\ConstraintTest, PHPUnit\Framework\ConstraintTest, PHPUnit\Framework\Constraint\ArraySubsetTest, PHPUnit\Framework\Constraint\ArraySubsetTest, PHPUnit\Framework\Constraint\CountTest, PHPUnit\Framework\Constraint\CountTest, PHPUnit\Framework\Constr...eptionMessageRegExpTest, PHPUnit\Framework\Constr...eptionMessageRegExpTest, PHPUnit\Framework\Constraint\ExceptionMessageTest, PHPUnit\Framework\Constraint\ExceptionMessageTest, PHPUnit\Framework\Constraint\IsJsonTest, PHPUnit\Framework\Constraint\IsJsonTest, PHPUnit\Framework\Constr...rrorMessageProviderTest, PHPUnit\Framework\Constr...rrorMessageProviderTest, PHPUnit\Framework\Constraint\JsonMatchesTest, PHPUnit\Framework\Constraint\JsonMatchesTest, PHPUnit\Framework\DataProviderTestSuite, PHPUnit\Framework\DataProviderTestSuite, PHPUnit\Framework\IncompleteTestCase, PHPUnit\Framework\IncompleteTestCase, PHPUnit\Framework\SkippedTestCase, PHPUnit\Framework\SkippedTestCase, PHPUnit\Framework\SuiteTest, PHPUnit\Framework\SuiteTest, PHPUnit\Framework\TestCase, PHPUnit\Framework\TestCase, PHPUnit\Framework\TestCaseTest, PHPUnit\Framework\TestCaseTest, PHPUnit\Framework\TestFailureTest, PHPUnit\Framework\TestFailureTest, PHPUnit\Framework\TestImplementorTest, PHPUnit\Framework\TestImplementorTest, PHPUnit\Framework\TestListenerTest, PHPUnit\Framework\TestListenerTest, PHPUnit\Framework\TestSuite, PHPUnit\Framework\TestSuite, PHPUnit\Framework\WarningTestCase, PHPUnit\Framework\WarningTestCase, PHPUnit\Runner\PhptTestCaseTest, PHPUnit\Runner\PhptTestCaseTest, PHPUnit\Util\ConfigurationTest, PHPUnit\Util\ConfigurationTest, PHPUnit\Util\GetoptTest, PHPUnit\Util\GetoptTest, PHPUnit\Util\GlobalStateTest, PHPUnit\Util\GlobalStateTest, PHPUnit\Util\PHP\AbstractPhpProcessTest, PHPUnit\Util\PHP\AbstractPhpProcessTest, PHPUnit\Util\RegularExpressionTest, PHPUnit\Util\RegularExpressionTest, PHPUnit\Util\TestDox\NamePrettifierTest, PHPUnit\Util\TestDox\NamePrettifierTest, PHPUnit\Util\TestTest, PHPUnit\Util\TestTest, PHPUnit\Util\XmlTest, PHPUnit\Util\XmlTest, PHP_TimerTest, PharIo\Manifest\ApplicationNameTest, PharIo\Manifest\ApplicationTest, PharIo\Manifest\AuthorCollectionTest, PharIo\Manifest\AuthorTest, PharIo\Manifest\BundledComponentCollectionTest, PharIo\Manifest\BundledComponentTest, PharIo\Manifest\CopyrightInformationTest, PharIo\Manifest\EmailTest, PharIo\Manifest\ExtensionTest, PharIo\Manifest\LibraryTest, PharIo\Manifest\LicenseTest, PharIo\Manifest\ManifestTest, PharIo\Manifest\PhpExtensionRequirementTest, PharIo\Manifest\PhpVersionRequirementTest, PharIo\Manifest\RequirementCollectionTest, PharIo\Manifest\UrlTest, PharIo\Version\AbstractVersionConstraintTest, PharIo\Version\AndVersionConstraintGroupTest, PharIo\Version\AnyVersionConstraintTest, PharIo\Version\ExactVersionConstraintTest, PharIo\Version\GreaterTh...ToVersionConstraintTest, PharIo\Version\OrVersionConstraintGroupTest, PharIo\Version\SpecificM...orVersionConstraintTest, PharIo\Version\SpecificMajorVersionConstraintTest, PharIo\Version\VersionConstraintParserTest, PharIo\Version\VersionTest, RequirementsClassBeforeClassHookTest, RequirementsClassBeforeClassHookTest, RequirementsTest, RequirementsTest, SebastianBergmann\CodeCoverage\CodeCoverageTest, SebastianBergmann\CodeCoverage\FilterTest, SebastianBergmann\CodeCoverage\Report\BuilderTest, SebastianBergmann\CodeCoverage\Report\CloverTest, SebastianBergmann\CodeCoverage\Report\Crap4jTest, SebastianBergmann\CodeCo...ge\Report\Html\HTMLTest, SebastianBergmann\CodeCoverage\Report\TextTest, SebastianBergmann\CodeCoverage\Report\Xml\XMLTest, SebastianBergmann\CodeCoverage\TestCase, SebastianBergmann\CodeCoverage\UtilTest, SebastianBergmann\CodeUnitReverseLookup\WizardTest, SebastianBergmann\Comparator\ArrayComparatorTest, SebastianBergmann\Comparator\DOMNodeComparatorTest, SebastianBergmann\Compar...\DateTimeComparatorTest, SebastianBergmann\Comparator\DoubleComparatorTest, SebastianBergmann\Compar...ExceptionComparatorTest, SebastianBergmann\Comparator\FactoryTest, SebastianBergmann\Compar...ockObjectComparatorTest, SebastianBergmann\Comparator\NumericComparatorTest, SebastianBergmann\Comparator\ObjectComparatorTest, SebastianBergmann\Compar...\ResourceComparatorTest, SebastianBergmann\Comparator\ScalarComparatorTest, SebastianBergmann\Compar...ctStorageComparatorTest, SebastianBergmann\Comparator\TypeComparatorTest, SebastianBergmann\Diff\ChunkTest, SebastianBergmann\Diff\DiffTest, SebastianBergmann\Diff\DifferTest, SebastianBergmann\Diff\L...stCommonSubsequenceTest, SebastianBergmann\Diff\L...cientImplementationTest, SebastianBergmann\Diff\L...cientImplementationTest, SebastianBergmann\Diff\LineTest, SebastianBergmann\Diff\ParserTest, SebastianBergmann\Environment\ConsoleTest, SebastianBergmann\Environment\RuntimeTest, SebastianBergmann\Exporter\ExporterTest, SebastianBergmann\GlobalState\BlacklistTest, SebastianBergmann\GlobalState\CodeExporterTest, SebastianBergmann\GlobalState\RestorerTest, SebastianBergmann\GlobalState\SnapshotTest, SebastianBergmann\ObjectEnumerator\EnumeratorTest, SebastianBergmann\Object...tor\ObjectReflectorTest, SebastianBergmann\RecursionContext\ContextTest, StackTest, StackTest, StopsOnWarningTest, StopsOnWarningTest, Success, Success, Symfony\Component\Config...\ConfigCacheFactoryTest, Symfony\Component\Config\Tests\ConfigCacheTest, Symfony\Component\Config...efinition\ArrayNodeTest, Symfony\Component\Config...inition\BooleanNodeTest, Symfony\Component\Config...ArrayNodeDefinitionTest, Symfony\Component\Config...oleanNodeDefinitionTest, Symfony\Component\Config...\EnumNodeDefinitionTest, Symfony\Component\Config...Builder\ExprBuilderTest, Symfony\Component\Config...Builder\NodeBuilderTest, Symfony\Component\Config...mericNodeDefinitionTest, Symfony\Component\Config...Builder\TreeBuilderTest, Symfony\Component\Config...\XmlReferenceDumperTest, Symfony\Component\Config...YamlReferenceDumperTest, Symfony\Component\Config...Definition\EnumNodeTest, Symfony\Component\Config...nition\FinalizationTest, Symfony\Component\Config...efinition\FloatNodeTest, Symfony\Component\Config...inition\IntegerNodeTest, Symfony\Component\Config...ts\Definition\MergeTest, Symfony\Component\Config...ition\NormalizationTest, Symfony\Component\Config...PrototypedArrayNodeTest, Symfony\Component\Config...finition\ScalarNodeTest, Symfony\Component\Config...ion\ConfigCachePassTest, Symfony\Component\Config...LoaderLoadExceptionTest, Symfony\Component\Config\Tests\FileLocatorTest, Symfony\Component\Config...er\DelegatingLoaderTest, Symfony\Component\Config...s\Loader\FileLoaderTest, Symfony\Component\Config...ader\LoaderResolverTest, Symfony\Component\Config\Tests\Loader\LoaderTest, Symfony\Component\Config...eCheckerConfigCacheTest, Symfony\Component\Config...ssExistenceResourceTest, Symfony\Component\Config...ce\ComposerResourceTest, Symfony\Component\Config...e\DirectoryResourceTest, Symfony\Component\Config...leExistenceResourceTest, Symfony\Component\Config...source\FileResourceTest, Symfony\Component\Config...source\GlobResourceTest, Symfony\Component\Config...ectionClassResourceTest, Symfony\Component\Config\Tests\Util\XmlUtilsTest, Symfony\Component\Console\Tests\ApplicationTest, Symfony\Component\Consol...sts\Command\CommandTest, Symfony\Component\Consol...Command\HelpCommandTest, Symfony\Component\Consol...Command\ListCommandTest, Symfony\Component\Consol...mmand\LockableTraitTest, Symfony\Component\Consol...dConsoleCommandPassTest, Symfony\Component\Consol...\AbstractDescriptorTest, Symfony\Component\Consol...ptor\JsonDescriptorTest, Symfony\Component\Consol...\MarkdownDescriptorTest, Symfony\Component\Consol...ptor\TextDescriptorTest, Symfony\Component\Consol...iptor\XmlDescriptorTest, Symfony\Component\Consol...tener\ErrorListenerTest, Symfony\Component\Consol...FormatterStyleStackTest, Symfony\Component\Consol...utputFormatterStyleTest, Symfony\Component\Consol...ter\OutputFormatterTest, Symfony\Component\Consol...tractQuestionHelperTest, Symfony\Component\Consol...per\FormatterHelperTest, Symfony\Component\Consol...ts\Helper\HelperSetTest, Symfony\Component\Console\Tests\Helper\HelperTest, Symfony\Component\Consol...elper\ProcessHelperTest, Symfony\Component\Consol...\Helper\ProgressBarTest, Symfony\Component\Consol...r\ProgressIndicatorTest, Symfony\Component\Consol...lper\QuestionHelperTest, Symfony\Component\Consol...mfonyQuestionHelperTest, Symfony\Component\Consol...s\Helper\TableStyleTest, Symfony\Component\Console\Tests\Helper\TableTest, Symfony\Component\Consol...sts\Input\ArgvInputTest, Symfony\Component\Consol...ts\Input\ArrayInputTest, Symfony\Component\Consol...Input\InputArgumentTest, Symfony\Component\Consol...put\InputDefinitionTest, Symfony\Component\Consol...s\Input\InputOptionTest, Symfony\Component\Console\Tests\Input\InputTest, Symfony\Component\Consol...s\Input\StringInputTest, Symfony\Component\Consol...ogger\ConsoleLoggerTest, Symfony\Component\Consol...utput\ConsoleOutputTest, Symfony\Component\Consol...s\Output\NullOutputTest, Symfony\Component\Console\Tests\Output\OutputTest, Symfony\Component\Consol...Output\StreamOutputTest, Symfony\Component\Consol...\Style\SymfonyStyleTest, Symfony\Component\Console\Tests\TerminalTest, Symfony\Component\Consol...r\ApplicationTesterTest, Symfony\Component\Consol...ester\CommandTesterTest, Symfony\Component\Debug\Tests\DebugClassLoaderTest, Symfony\Component\Debug\Tests\ErrorHandlerTest, Symfony\Component\Debug\Tests\ExceptionHandlerTest, Symfony\Component\Debug\...on\FlattenExceptionTest, Symfony\Component\Debug\...ndFatalErrorHandlerTest, Symfony\Component\Debug\...onFatalErrorHandlerTest, Symfony\Component\Debug\...odFatalErrorHandlerTest, Symfony\Component\EventD...ractEventDispatcherTest, Symfony\Component\EventD...wareEventDispatcherTest, Symfony\Component\EventD...ableEventDispatcherTest, Symfony\Component\EventD...gisterListenersPassTest, Symfony\Component\EventD...sts\EventDispatcherTest, Symfony\Component\EventDispatcher\Tests\EventTest, Symfony\Component\EventD...\Tests\GenericEventTest, Symfony\Component\EventD...ableEventDispatcherTest, Symfony\Component\Filesystem\Tests\ExceptionTest, Symfony\Component\Filesystem\Tests\FilesystemTest, Symfony\Component\Filesy...ests\FilesystemTestCase, Symfony\Component\Filesystem\Tests\LockHandlerTest, Symfony\Component\Stopwa...ests\StopwatchEventTest, Symfony\Component\Stopwatch\Tests\StopwatchTest, Symfony\Component\Yaml\T...Command\LintCommandTest, Symfony\Component\Yaml\Tests\DumperTest, Symfony\Component\Yaml\Tests\InlineTest, Symfony\Component\Yaml\Tests\ParseExceptionTest, Symfony\Component\Yaml\Tests\ParserTest, Symfony\Component\Yaml\Tests\YamlTest, TemplateMethodsTest, TemplateMethodsTest, Test, TestAutoreferenced, TestAutoreferenced, TestDoxGroupTest, TestDoxGroupTest, TestError, TestError, TestIncomplete, TestIncomplete, TestSkipped, TestSkipped, TestWithTest, TestWithTest, TheSeer\Tokenizer\NamespaceUriTest, TheSeer\Tokenizer\TokenCollectionTest, TheSeer\Tokenizer\TokenTest, TheSeer\Tokenizer\TokenizerTest, TheSeer\Tokenizer\XMLSerializerTest, ThrowExceptionTestCase, ThrowExceptionTestCase, ThrowNoExceptionTestCase, ThrowNoExceptionTestCase, TwoTest, TwoTest, WasRun, WasRun, vendor\project\StatusTest, vendor\project\StatusTest.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
206
        }
207
208
        if (\is_int($arguments['repeat']) && $arguments['repeat'] > 0) {
209
            $_suite = new TestSuite;
210
211
            foreach (\range(1, $arguments['repeat']) as $step) {
212
                $_suite->addTest($suite);
213
            }
214
215
            $suite = $_suite;
216
            unset($_suite);
217
        }
218
219
        $result = $this->createTestResult();
220
221
        if (!$arguments['convertErrorsToExceptions']) {
222
            $result->convertErrorsToExceptions(false);
223
        }
224
225
        if (!$arguments['convertNoticesToExceptions']) {
226
            Notice::$enabled = false;
227
        }
228
229
        if (!$arguments['convertWarningsToExceptions']) {
230
            Warning::$enabled = false;
231
        }
232
233
        if ($arguments['stopOnError']) {
234
            $result->stopOnError(true);
235
        }
236
237
        if ($arguments['stopOnFailure']) {
238
            $result->stopOnFailure(true);
239
        }
240
241
        if ($arguments['stopOnWarning']) {
242
            $result->stopOnWarning(true);
243
        }
244
245
        if ($arguments['stopOnIncomplete']) {
246
            $result->stopOnIncomplete(true);
247
        }
248
249
        if ($arguments['stopOnRisky']) {
250
            $result->stopOnRisky(true);
251
        }
252
253
        if ($arguments['stopOnSkipped']) {
254
            $result->stopOnSkipped(true);
255
        }
256
257
        if ($arguments['registerMockObjectsFromTestArgumentsRecursively']) {
258
            $result->setRegisterMockObjectsFromTestArgumentsRecursively(true);
259
        }
260
261
        if ($this->printer === null) {
262
            if (isset($arguments['printer']) &&
263
                $arguments['printer'] instanceof Printer) {
264
                $this->printer = $arguments['printer'];
0 ignored issues
show
Documentation Bug introduced by
$arguments['printer'] is of type object<PHPUnit\Util\Printer>, but the property $printer was declared to be of type object<PHPUnit\TextUI\ResultPrinter>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
265
            } else {
266
                $printerClass = ResultPrinter::class;
267
268
                if (isset($arguments['printer']) && \is_string($arguments['printer']) && \class_exists($arguments['printer'], false)) {
269
                    $class = new ReflectionClass($arguments['printer']);
270
271
                    if ($class->isSubclassOf(ResultPrinter::class)) {
272
                        $printerClass = $arguments['printer'];
273
                    }
274
                }
275
276
                $this->printer = new $printerClass(
277
                    isset($arguments['stderr']) ? 'php://stderr' : null,
278
                    $arguments['verbose'],
279
                    $arguments['colors'],
280
                    $arguments['debug'],
281
                    $arguments['columns'],
282
                    $arguments['reverseList']
283
                );
284
            }
285
        }
286
287
        $this->printer->write(
288
            Version::getVersionString() . "\n"
289
        );
290
291
        self::$versionStringPrinted = true;
292
293
        if ($arguments['verbose']) {
294
            $runtime = $this->runtime->getNameWithVersion();
295
296
            if ($this->runtime->hasXdebug()) {
297
                $runtime .= \sprintf(
298
                    ' with Xdebug %s',
299
                    \phpversion('xdebug')
300
                );
301
            }
302
303
            $this->writeMessage('Runtime', $runtime);
304
305
            if (isset($arguments['configuration'])) {
306
                $this->writeMessage(
307
                    'Configuration',
308
                    $arguments['configuration']->getFilename()
309
                );
310
            }
311
312
            foreach ($arguments['loadedExtensions'] as $extension) {
313
                $this->writeMessage(
314
                    'Extension',
315
                    $extension
316
                );
317
            }
318
319
            foreach ($arguments['notLoadedExtensions'] as $extension) {
320
                $this->writeMessage(
321
                    'Extension',
322
                    $extension
323
                );
324
            }
325
        }
326
327
        foreach ($arguments['listeners'] as $listener) {
328
            $result->addListener($listener);
329
        }
330
331
        $result->addListener($this->printer);
332
333
        if (isset($arguments['testdoxHTMLFile'])) {
334
            $result->addListener(
335
                new HtmlResultPrinter(
336
                    $arguments['testdoxHTMLFile'],
337
                    $arguments['testdoxGroups'],
338
                    $arguments['testdoxExcludeGroups']
339
                )
340
            );
341
        }
342
343
        if (isset($arguments['testdoxTextFile'])) {
344
            $result->addListener(
345
                new TextResultPrinter(
346
                    $arguments['testdoxTextFile'],
347
                    $arguments['testdoxGroups'],
348
                    $arguments['testdoxExcludeGroups']
349
                )
350
            );
351
        }
352
353
        if (isset($arguments['testdoxXMLFile'])) {
354
            $result->addListener(
355
                new XmlResultPrinter(
356
                    $arguments['testdoxXMLFile']
357
                )
358
            );
359
        }
360
361
        $codeCoverageReports = 0;
362
363
        if (isset($arguments['coverageClover'])) {
364
            $codeCoverageReports++;
365
        }
366
367
        if (isset($arguments['coverageCrap4J'])) {
368
            $codeCoverageReports++;
369
        }
370
371
        if (isset($arguments['coverageHtml'])) {
372
            $codeCoverageReports++;
373
        }
374
375
        if (isset($arguments['coveragePHP'])) {
376
            $codeCoverageReports++;
377
        }
378
379
        if (isset($arguments['coverageText'])) {
380
            $codeCoverageReports++;
381
        }
382
383
        if (isset($arguments['coverageXml'])) {
384
            $codeCoverageReports++;
385
        }
386
387
        if (isset($arguments['noCoverage'])) {
388
            $codeCoverageReports = 0;
389
        }
390
391
        if ($codeCoverageReports > 0 && !$this->runtime->canCollectCodeCoverage()) {
392
            $this->writeMessage('Error', 'No code coverage driver is available');
393
394
            $codeCoverageReports = 0;
395
        }
396
397
        if ($codeCoverageReports > 0) {
398
            $codeCoverage = new CodeCoverage(
399
                null,
400
                $this->codeCoverageFilter
401
            );
402
403
            $codeCoverage->setUnintentionallyCoveredSubclassesWhitelist(
404
                [SebastianBergmann\Comparator\Comparator::class]
405
            );
406
407
            $codeCoverage->setCheckForUnintentionallyCoveredCode(
408
                $arguments['strictCoverage']
409
            );
410
411
            $codeCoverage->setCheckForMissingCoversAnnotation(
412
                $arguments['strictCoverage']
413
            );
414
415
            if (isset($arguments['forceCoversAnnotation'])) {
416
                $codeCoverage->setForceCoversAnnotation(
417
                    $arguments['forceCoversAnnotation']
418
                );
419
            }
420
421
            if (isset($arguments['ignoreDeprecatedCodeUnitsFromCodeCoverage'])) {
422
                $codeCoverage->setIgnoreDeprecatedCode(
423
                    $arguments['ignoreDeprecatedCodeUnitsFromCodeCoverage']
424
                );
425
            }
426
427
            if (isset($arguments['disableCodeCoverageIgnore'])) {
428
                $codeCoverage->setDisableIgnoredLines(true);
429
            }
430
431
            if (isset($arguments['whitelist'])) {
432
                $this->codeCoverageFilter->addDirectoryToWhitelist($arguments['whitelist']);
433
            }
434
435
            if (isset($arguments['configuration'])) {
436
                $filterConfiguration = $arguments['configuration']->getFilterConfiguration();
437
438
                if (empty($filterConfiguration['whitelist'])) {
439
                    $this->writeMessage('Error', 'No whitelist is configured, no code coverage will be generated.');
440
441
                    $codeCoverageReports = 0;
442
443
                    unset($codeCoverage);
444
                } else {
445
                    $codeCoverage->setAddUncoveredFilesFromWhitelist(
446
                        $filterConfiguration['whitelist']['addUncoveredFilesFromWhitelist']
447
                    );
448
449
                    $codeCoverage->setProcessUncoveredFilesFromWhitelist(
450
                        $filterConfiguration['whitelist']['processUncoveredFilesFromWhitelist']
451
                    );
452
453
                    foreach ($filterConfiguration['whitelist']['include']['directory'] as $dir) {
454
                        $this->codeCoverageFilter->addDirectoryToWhitelist(
455
                            $dir['path'],
456
                            $dir['suffix'],
457
                            $dir['prefix']
458
                        );
459
                    }
460
461
                    foreach ($filterConfiguration['whitelist']['include']['file'] as $file) {
462
                        $this->codeCoverageFilter->addFileToWhitelist($file);
463
                    }
464
465
                    foreach ($filterConfiguration['whitelist']['exclude']['directory'] as $dir) {
466
                        $this->codeCoverageFilter->removeDirectoryFromWhitelist(
467
                            $dir['path'],
468
                            $dir['suffix'],
469
                            $dir['prefix']
470
                        );
471
                    }
472
473
                    foreach ($filterConfiguration['whitelist']['exclude']['file'] as $file) {
474
                        $this->codeCoverageFilter->removeFileFromWhitelist($file);
475
                    }
476
                }
477
            }
478
479
            if (isset($codeCoverage) && !$this->codeCoverageFilter->hasWhitelist()) {
480
                $this->writeMessage('Error', 'Incorrect whitelist config, no code coverage will be generated.');
481
482
                $codeCoverageReports = 0;
483
484
                unset($codeCoverage);
485
            }
486
        }
487
488
        $this->printer->write("\n");
489
490
        if (isset($codeCoverage)) {
491
            $result->setCodeCoverage($codeCoverage);
492
493
            if ($codeCoverageReports > 1 && isset($arguments['cacheTokens'])) {
494
                $codeCoverage->setCacheTokens($arguments['cacheTokens']);
495
            }
496
        }
497
498
        if (isset($arguments['teamcityLogfile'])) {
499
            $result->addListener(
500
                new TeamCity($arguments['teamcityLogfile'])
501
            );
502
        }
503
504
        if (isset($arguments['junitLogfile'])) {
505
            $result->addListener(
506
                new JUnit(
507
                    $arguments['junitLogfile'],
508
                    $arguments['reportUselessTests']
509
                )
510
            );
511
        }
512
513
        $result->beStrictAboutTestsThatDoNotTestAnything($arguments['reportUselessTests']);
514
        $result->beStrictAboutOutputDuringTests($arguments['disallowTestOutput']);
515
        $result->beStrictAboutTodoAnnotatedTests($arguments['disallowTodoAnnotatedTests']);
516
        $result->beStrictAboutResourceUsageDuringSmallTests($arguments['beStrictAboutResourceUsageDuringSmallTests']);
517
        $result->enforceTimeLimit($arguments['enforceTimeLimit']);
518
        $result->setTimeoutForSmallTests($arguments['timeoutForSmallTests']);
519
        $result->setTimeoutForMediumTests($arguments['timeoutForMediumTests']);
520
        $result->setTimeoutForLargeTests($arguments['timeoutForLargeTests']);
521
522
        if ($suite instanceof TestSuite) {
523
            $suite->setRunTestInSeparateProcess($arguments['processIsolation']);
524
        }
525
526
        $suite->run($result);
527
528
        unset($suite);
529
        $result->flushListeners();
530
531
        if ($this->printer instanceof ResultPrinter) {
532
            $this->printer->printResult($result);
533
        }
534
535
        if (isset($codeCoverage)) {
536
            if (isset($arguments['coverageClover'])) {
537
                $this->printer->write(
538
                    "\nGenerating code coverage report in Clover XML format ..."
539
                );
540
541
                try {
542
                    $writer = new CloverReport;
543
                    $writer->process($codeCoverage, $arguments['coverageClover']);
544
545
                    $this->printer->write(" done\n");
546
                    unset($writer);
547
                } catch (CodeCoverageException $e) {
548
                    $this->printer->write(
549
                        " failed\n" . $e->getMessage() . "\n"
550
                    );
551
                }
552
            }
553
554
            if (isset($arguments['coverageCrap4J'])) {
555
                $this->printer->write(
556
                    "\nGenerating Crap4J report XML file ..."
557
                );
558
559
                try {
560
                    $writer = new Crap4jReport($arguments['crap4jThreshold']);
561
                    $writer->process($codeCoverage, $arguments['coverageCrap4J']);
562
563
                    $this->printer->write(" done\n");
564
                    unset($writer);
565
                } catch (CodeCoverageException $e) {
566
                    $this->printer->write(
567
                        " failed\n" . $e->getMessage() . "\n"
568
                    );
569
                }
570
            }
571
572
            if (isset($arguments['coverageHtml'])) {
573
                $this->printer->write(
574
                    "\nGenerating code coverage report in HTML format ..."
575
                );
576
577
                try {
578
                    $writer = new HtmlReport(
579
                        $arguments['reportLowUpperBound'],
580
                        $arguments['reportHighLowerBound'],
581
                        \sprintf(
582
                            ' and <a href="https://phpunit.de/">PHPUnit %s</a>',
583
                            Version::id()
584
                        )
585
                    );
586
587
                    $writer->process($codeCoverage, $arguments['coverageHtml']);
588
589
                    $this->printer->write(" done\n");
590
                    unset($writer);
591
                } catch (CodeCoverageException $e) {
592
                    $this->printer->write(
593
                        " failed\n" . $e->getMessage() . "\n"
594
                    );
595
                }
596
            }
597
598
            if (isset($arguments['coveragePHP'])) {
599
                $this->printer->write(
600
                    "\nGenerating code coverage report in PHP format ..."
601
                );
602
603
                try {
604
                    $writer = new PhpReport;
605
                    $writer->process($codeCoverage, $arguments['coveragePHP']);
606
607
                    $this->printer->write(" done\n");
608
                    unset($writer);
609
                } catch (CodeCoverageException $e) {
610
                    $this->printer->write(
611
                        " failed\n" . $e->getMessage() . "\n"
612
                    );
613
                }
614
            }
615
616
            if (isset($arguments['coverageText'])) {
617
                if ($arguments['coverageText'] == 'php://stdout') {
618
                    $outputStream = $this->printer;
619
                    $colors       = $arguments['colors'] && $arguments['colors'] != ResultPrinter::COLOR_NEVER;
620
                } else {
621
                    $outputStream = new Printer($arguments['coverageText']);
622
                    $colors       = false;
623
                }
624
625
                $processor = new TextReport(
626
                    $arguments['reportLowUpperBound'],
627
                    $arguments['reportHighLowerBound'],
628
                    $arguments['coverageTextShowUncoveredFiles'],
629
                    $arguments['coverageTextShowOnlySummary']
630
                );
631
632
                $outputStream->write(
633
                    $processor->process($codeCoverage, $colors)
634
                );
635
            }
636
637
            if (isset($arguments['coverageXml'])) {
638
                $this->printer->write(
639
                    "\nGenerating code coverage report in PHPUnit XML format ..."
640
                );
641
642
                try {
643
                    $writer = new XmlReport(Version::id());
644
                    $writer->process($codeCoverage, $arguments['coverageXml']);
645
646
                    $this->printer->write(" done\n");
647
                    unset($writer);
648
                } catch (CodeCoverageException $e) {
649
                    $this->printer->write(
650
                        " failed\n" . $e->getMessage() . "\n"
651
                    );
652
                }
653
            }
654
        }
655
656
        if ($exit) {
657
            if ($result->wasSuccessful()) {
658
                if ($arguments['failOnRisky'] && !$result->allHarmless()) {
659
                    exit(self::FAILURE_EXIT);
660
                }
661
662
                if ($arguments['failOnWarning'] && $result->warningCount() > 0) {
663
                    exit(self::FAILURE_EXIT);
664
                }
665
666
                exit(self::SUCCESS_EXIT);
667
            }
668
669
            if ($result->errorCount() > 0) {
670
                exit(self::EXCEPTION_EXIT);
671
            }
672
673
            if ($result->failureCount() > 0) {
674
                exit(self::FAILURE_EXIT);
675
            }
676
        }
677
678
        return $result;
679
    }
680
681
    /**
682
     * @param ResultPrinter $resultPrinter
683
     */
684
    public function setPrinter(ResultPrinter $resultPrinter)
685
    {
686
        $this->printer = $resultPrinter;
687
    }
688
689
    /**
690
     * Override to define how to handle a failed loading of
691
     * a test suite.
692
     *
693
     * @param string $message
694
     */
695
    protected function runFailed($message)
696
    {
697
        $this->write($message . PHP_EOL);
698
        exit(self::FAILURE_EXIT);
699
    }
700
701
    /**
702
     * @param string $buffer
703
     */
704
    protected function write($buffer)
705
    {
706
        if (PHP_SAPI != 'cli' && PHP_SAPI != 'phpdbg') {
707
            $buffer = \htmlspecialchars($buffer);
708
        }
709
710
        if ($this->printer !== null) {
711
            $this->printer->write($buffer);
712
        } else {
713
            print $buffer;
714
        }
715
    }
716
717
    /**
718
     * Returns the loader to be used.
719
     *
720
     * @return TestSuiteLoader
721
     */
722
    public function getLoader()
723
    {
724
        if ($this->loader === null) {
725
            $this->loader = new StandardTestSuiteLoader;
726
        }
727
728
        return $this->loader;
729
    }
730
731
    /**
732
     * @param array $arguments
733
     */
734
    protected function handleConfiguration(array &$arguments)
735
    {
736
        if (isset($arguments['configuration']) &&
737
            !$arguments['configuration'] instanceof Configuration) {
738
            $arguments['configuration'] = Configuration::getInstance(
739
                $arguments['configuration']
740
            );
741
        }
742
743
        $arguments['debug']     = $arguments['debug'] ?? false;
744
        $arguments['filter']    = $arguments['filter'] ?? false;
745
        $arguments['listeners'] = $arguments['listeners'] ?? [];
746
747
        if (isset($arguments['configuration'])) {
748
            $arguments['configuration']->handlePHPConfiguration();
749
750
            $phpunitConfiguration = $arguments['configuration']->getPHPUnitConfiguration();
751
752
            if (isset($phpunitConfiguration['backupGlobals']) && !isset($arguments['backupGlobals'])) {
753
                $arguments['backupGlobals'] = $phpunitConfiguration['backupGlobals'];
754
            }
755
756
            if (isset($phpunitConfiguration['backupStaticAttributes']) && !isset($arguments['backupStaticAttributes'])) {
757
                $arguments['backupStaticAttributes'] = $phpunitConfiguration['backupStaticAttributes'];
758
            }
759
760
            if (isset($phpunitConfiguration['beStrictAboutChangesToGlobalState']) && !isset($arguments['beStrictAboutChangesToGlobalState'])) {
761
                $arguments['beStrictAboutChangesToGlobalState'] = $phpunitConfiguration['beStrictAboutChangesToGlobalState'];
762
            }
763
764
            if (isset($phpunitConfiguration['bootstrap']) && !isset($arguments['bootstrap'])) {
765
                $arguments['bootstrap'] = $phpunitConfiguration['bootstrap'];
766
            }
767
768
            if (isset($phpunitConfiguration['cacheTokens']) && !isset($arguments['cacheTokens'])) {
769
                $arguments['cacheTokens'] = $phpunitConfiguration['cacheTokens'];
770
            }
771
772
            if (isset($phpunitConfiguration['colors']) && !isset($arguments['colors'])) {
773
                $arguments['colors'] = $phpunitConfiguration['colors'];
774
            }
775
776
            if (isset($phpunitConfiguration['convertErrorsToExceptions']) && !isset($arguments['convertErrorsToExceptions'])) {
777
                $arguments['convertErrorsToExceptions'] = $phpunitConfiguration['convertErrorsToExceptions'];
778
            }
779
780
            if (isset($phpunitConfiguration['convertNoticesToExceptions']) && !isset($arguments['convertNoticesToExceptions'])) {
781
                $arguments['convertNoticesToExceptions'] = $phpunitConfiguration['convertNoticesToExceptions'];
782
            }
783
784
            if (isset($phpunitConfiguration['convertWarningsToExceptions']) && !isset($arguments['convertWarningsToExceptions'])) {
785
                $arguments['convertWarningsToExceptions'] = $phpunitConfiguration['convertWarningsToExceptions'];
786
            }
787
788
            if (isset($phpunitConfiguration['processIsolation']) && !isset($arguments['processIsolation'])) {
789
                $arguments['processIsolation'] = $phpunitConfiguration['processIsolation'];
790
            }
791
792
            if (isset($phpunitConfiguration['stopOnError']) && !isset($arguments['stopOnError'])) {
793
                $arguments['stopOnError'] = $phpunitConfiguration['stopOnError'];
794
            }
795
796
            if (isset($phpunitConfiguration['stopOnFailure']) && !isset($arguments['stopOnFailure'])) {
797
                $arguments['stopOnFailure'] = $phpunitConfiguration['stopOnFailure'];
798
            }
799
800
            if (isset($phpunitConfiguration['stopOnWarning']) && !isset($arguments['stopOnWarning'])) {
801
                $arguments['stopOnWarning'] = $phpunitConfiguration['stopOnWarning'];
802
            }
803
804
            if (isset($phpunitConfiguration['stopOnIncomplete']) && !isset($arguments['stopOnIncomplete'])) {
805
                $arguments['stopOnIncomplete'] = $phpunitConfiguration['stopOnIncomplete'];
806
            }
807
808
            if (isset($phpunitConfiguration['stopOnRisky']) && !isset($arguments['stopOnRisky'])) {
809
                $arguments['stopOnRisky'] = $phpunitConfiguration['stopOnRisky'];
810
            }
811
812
            if (isset($phpunitConfiguration['stopOnSkipped']) && !isset($arguments['stopOnSkipped'])) {
813
                $arguments['stopOnSkipped'] = $phpunitConfiguration['stopOnSkipped'];
814
            }
815
816
            if (isset($phpunitConfiguration['failOnWarning']) && !isset($arguments['failOnWarning'])) {
817
                $arguments['failOnWarning'] = $phpunitConfiguration['failOnWarning'];
818
            }
819
820
            if (isset($phpunitConfiguration['failOnRisky']) && !isset($arguments['failOnRisky'])) {
821
                $arguments['failOnRisky'] = $phpunitConfiguration['failOnRisky'];
822
            }
823
824
            if (isset($phpunitConfiguration['timeoutForSmallTests']) && !isset($arguments['timeoutForSmallTests'])) {
825
                $arguments['timeoutForSmallTests'] = $phpunitConfiguration['timeoutForSmallTests'];
826
            }
827
828
            if (isset($phpunitConfiguration['timeoutForMediumTests']) && !isset($arguments['timeoutForMediumTests'])) {
829
                $arguments['timeoutForMediumTests'] = $phpunitConfiguration['timeoutForMediumTests'];
830
            }
831
832
            if (isset($phpunitConfiguration['timeoutForLargeTests']) && !isset($arguments['timeoutForLargeTests'])) {
833
                $arguments['timeoutForLargeTests'] = $phpunitConfiguration['timeoutForLargeTests'];
834
            }
835
836
            if (isset($phpunitConfiguration['reportUselessTests']) && !isset($arguments['reportUselessTests'])) {
837
                $arguments['reportUselessTests'] = $phpunitConfiguration['reportUselessTests'];
838
            }
839
840
            if (isset($phpunitConfiguration['strictCoverage']) && !isset($arguments['strictCoverage'])) {
841
                $arguments['strictCoverage'] = $phpunitConfiguration['strictCoverage'];
842
            }
843
844
            if (isset($phpunitConfiguration['ignoreDeprecatedCodeUnitsFromCodeCoverage']) && !isset($arguments['ignoreDeprecatedCodeUnitsFromCodeCoverage'])) {
845
                $arguments['ignoreDeprecatedCodeUnitsFromCodeCoverage'] = $phpunitConfiguration['ignoreDeprecatedCodeUnitsFromCodeCoverage'];
846
            }
847
848
            if (isset($phpunitConfiguration['disallowTestOutput']) && !isset($arguments['disallowTestOutput'])) {
849
                $arguments['disallowTestOutput'] = $phpunitConfiguration['disallowTestOutput'];
850
            }
851
852
            if (isset($phpunitConfiguration['enforceTimeLimit']) && !isset($arguments['enforceTimeLimit'])) {
853
                $arguments['enforceTimeLimit'] = $phpunitConfiguration['enforceTimeLimit'];
854
            }
855
856
            if (isset($phpunitConfiguration['disallowTodoAnnotatedTests']) && !isset($arguments['disallowTodoAnnotatedTests'])) {
857
                $arguments['disallowTodoAnnotatedTests'] = $phpunitConfiguration['disallowTodoAnnotatedTests'];
858
            }
859
860
            if (isset($phpunitConfiguration['beStrictAboutResourceUsageDuringSmallTests']) && !isset($arguments['beStrictAboutResourceUsageDuringSmallTests'])) {
861
                $arguments['beStrictAboutResourceUsageDuringSmallTests'] = $phpunitConfiguration['beStrictAboutResourceUsageDuringSmallTests'];
862
            }
863
864
            if (isset($phpunitConfiguration['verbose']) && !isset($arguments['verbose'])) {
865
                $arguments['verbose'] = $phpunitConfiguration['verbose'];
866
            }
867
868
            if (isset($phpunitConfiguration['reverseDefectList']) && !isset($arguments['reverseList'])) {
869
                $arguments['reverseList'] = $phpunitConfiguration['reverseDefectList'];
870
            }
871
872
            if (isset($phpunitConfiguration['forceCoversAnnotation']) && !isset($arguments['forceCoversAnnotation'])) {
873
                $arguments['forceCoversAnnotation'] = $phpunitConfiguration['forceCoversAnnotation'];
874
            }
875
876
            if (isset($phpunitConfiguration['disableCodeCoverageIgnore']) && !isset($arguments['disableCodeCoverageIgnore'])) {
877
                $arguments['disableCodeCoverageIgnore'] = $phpunitConfiguration['disableCodeCoverageIgnore'];
878
            }
879
880
            if (isset($phpunitConfiguration['registerMockObjectsFromTestArgumentsRecursively']) && !isset($arguments['registerMockObjectsFromTestArgumentsRecursively'])) {
881
                $arguments['registerMockObjectsFromTestArgumentsRecursively'] = $phpunitConfiguration['registerMockObjectsFromTestArgumentsRecursively'];
882
            }
883
884
            $groupCliArgs = [];
885
886
            if (!empty($arguments['groups'])) {
887
                $groupCliArgs = $arguments['groups'];
888
            }
889
890
            $groupConfiguration = $arguments['configuration']->getGroupConfiguration();
891
892
            if (!empty($groupConfiguration['include']) && !isset($arguments['groups'])) {
893
                $arguments['groups'] = $groupConfiguration['include'];
894
            }
895
896
            if (!empty($groupConfiguration['exclude']) && !isset($arguments['excludeGroups'])) {
897
                $arguments['excludeGroups'] = \array_diff($groupConfiguration['exclude'], $groupCliArgs);
898
            }
899
900
            foreach ($arguments['configuration']->getListenerConfiguration() as $listener) {
901
                if (!\class_exists($listener['class'], false) &&
902
                    $listener['file'] !== '') {
903
                    require_once $listener['file'];
904
                }
905
906
                if (!\class_exists($listener['class'])) {
907
                    throw new Exception(
908
                        \sprintf(
909
                            'Class "%s" does not exist',
910
                            $listener['class']
911
                        )
912
                    );
913
                }
914
915
                $listenerClass = new ReflectionClass($listener['class']);
916
917
                if (!$listenerClass->implementsInterface(TestListener::class)) {
918
                    throw new Exception(
919
                        \sprintf(
920
                            'Class "%s" does not implement the PHPUnit\Framework\TestListener interface',
921
                            $listener['class']
922
                        )
923
                    );
924
                }
925
926
                if (\count($listener['arguments']) == 0) {
927
                    $listener = new $listener['class'];
928
                } else {
929
                    $listener = $listenerClass->newInstanceArgs(
930
                        $listener['arguments']
931
                    );
932
                }
933
934
                $arguments['listeners'][] = $listener;
935
            }
936
937
            $loggingConfiguration = $arguments['configuration']->getLoggingConfiguration();
938
939
            if (isset($loggingConfiguration['coverage-clover']) && !isset($arguments['coverageClover'])) {
940
                $arguments['coverageClover'] = $loggingConfiguration['coverage-clover'];
941
            }
942
943
            if (isset($loggingConfiguration['coverage-crap4j']) && !isset($arguments['coverageCrap4J'])) {
944
                $arguments['coverageCrap4J'] = $loggingConfiguration['coverage-crap4j'];
945
946
                if (isset($loggingConfiguration['crap4jThreshold']) && !isset($arguments['crap4jThreshold'])) {
947
                    $arguments['crap4jThreshold'] = $loggingConfiguration['crap4jThreshold'];
948
                }
949
            }
950
951
            if (isset($loggingConfiguration['coverage-html']) && !isset($arguments['coverageHtml'])) {
952
                if (isset($loggingConfiguration['lowUpperBound']) && !isset($arguments['reportLowUpperBound'])) {
953
                    $arguments['reportLowUpperBound'] = $loggingConfiguration['lowUpperBound'];
954
                }
955
956
                if (isset($loggingConfiguration['highLowerBound']) && !isset($arguments['reportHighLowerBound'])) {
957
                    $arguments['reportHighLowerBound'] = $loggingConfiguration['highLowerBound'];
958
                }
959
960
                $arguments['coverageHtml'] = $loggingConfiguration['coverage-html'];
961
            }
962
963
            if (isset($loggingConfiguration['coverage-php']) && !isset($arguments['coveragePHP'])) {
964
                $arguments['coveragePHP'] = $loggingConfiguration['coverage-php'];
965
            }
966
967
            if (isset($loggingConfiguration['coverage-text']) && !isset($arguments['coverageText'])) {
968
                $arguments['coverageText'] = $loggingConfiguration['coverage-text'];
969
970
                if (isset($loggingConfiguration['coverageTextShowUncoveredFiles'])) {
971
                    $arguments['coverageTextShowUncoveredFiles'] = $loggingConfiguration['coverageTextShowUncoveredFiles'];
972
                } else {
973
                    $arguments['coverageTextShowUncoveredFiles'] = false;
974
                }
975
976
                if (isset($loggingConfiguration['coverageTextShowOnlySummary'])) {
977
                    $arguments['coverageTextShowOnlySummary'] = $loggingConfiguration['coverageTextShowOnlySummary'];
978
                } else {
979
                    $arguments['coverageTextShowOnlySummary'] = false;
980
                }
981
            }
982
983
            if (isset($loggingConfiguration['coverage-xml']) && !isset($arguments['coverageXml'])) {
984
                $arguments['coverageXml'] = $loggingConfiguration['coverage-xml'];
985
            }
986
987
            if (isset($loggingConfiguration['plain'])) {
988
                $arguments['listeners'][] = new ResultPrinter(
989
                    $loggingConfiguration['plain'],
990
                    true
991
                );
992
            }
993
994
            if (isset($loggingConfiguration['teamcity']) && !isset($arguments['teamcityLogfile'])) {
995
                $arguments['teamcityLogfile'] = $loggingConfiguration['teamcity'];
996
            }
997
998
            if (isset($loggingConfiguration['junit']) && !isset($arguments['junitLogfile'])) {
999
                $arguments['junitLogfile'] = $loggingConfiguration['junit'];
1000
            }
1001
1002
            if (isset($loggingConfiguration['testdox-html']) && !isset($arguments['testdoxHTMLFile'])) {
1003
                $arguments['testdoxHTMLFile'] = $loggingConfiguration['testdox-html'];
1004
            }
1005
1006
            if (isset($loggingConfiguration['testdox-text']) && !isset($arguments['testdoxTextFile'])) {
1007
                $arguments['testdoxTextFile'] = $loggingConfiguration['testdox-text'];
1008
            }
1009
1010
            if (isset($loggingConfiguration['testdox-xml']) && !isset($arguments['testdoxXMLFile'])) {
1011
                $arguments['testdoxXMLFile'] = $loggingConfiguration['testdox-xml'];
1012
            }
1013
1014
            $testdoxGroupConfiguration = $arguments['configuration']->getTestdoxGroupConfiguration();
1015
1016
            if (isset($testdoxGroupConfiguration['include']) &&
1017
                !isset($arguments['testdoxGroups'])) {
1018
                $arguments['testdoxGroups'] = $testdoxGroupConfiguration['include'];
1019
            }
1020
1021
            if (isset($testdoxGroupConfiguration['exclude']) &&
1022
                !isset($arguments['testdoxExcludeGroups'])) {
1023
                $arguments['testdoxExcludeGroups'] = $testdoxGroupConfiguration['exclude'];
1024
            }
1025
        }
1026
1027
        $arguments['addUncoveredFilesFromWhitelist']                  = $arguments['addUncoveredFilesFromWhitelist'] ?? true;
1028
        $arguments['backupGlobals']                                   = $arguments['backupGlobals'] ?? null;
1029
        $arguments['backupStaticAttributes']                          = $arguments['backupStaticAttributes'] ?? null;
1030
        $arguments['beStrictAboutChangesToGlobalState']               = $arguments['beStrictAboutChangesToGlobalState'] ?? null;
1031
        $arguments['beStrictAboutResourceUsageDuringSmallTests']      = $arguments['beStrictAboutResourceUsageDuringSmallTests'] ?? false;
1032
        $arguments['cacheTokens']                                     = $arguments['cacheTokens'] ?? false;
1033
        $arguments['colors']                                          = $arguments['colors'] ?? ResultPrinter::COLOR_DEFAULT;
1034
        $arguments['columns']                                         = $arguments['columns'] ?? 80;
1035
        $arguments['convertErrorsToExceptions']                       = $arguments['convertErrorsToExceptions'] ?? true;
1036
        $arguments['convertNoticesToExceptions']                      = $arguments['convertNoticesToExceptions'] ?? true;
1037
        $arguments['convertWarningsToExceptions']                     = $arguments['convertWarningsToExceptions'] ?? true;
1038
        $arguments['crap4jThreshold']                                 = $arguments['crap4jThreshold'] ?? 30;
1039
        $arguments['disallowTestOutput']                              = $arguments['disallowTestOutput'] ?? false;
1040
        $arguments['disallowTodoAnnotatedTests']                      = $arguments['disallowTodoAnnotatedTests'] ?? false;
1041
        $arguments['enforceTimeLimit']                                = $arguments['enforceTimeLimit'] ?? false;
1042
        $arguments['excludeGroups']                                   = $arguments['excludeGroups'] ?? [];
1043
        $arguments['failOnRisky']                                     = $arguments['failOnRisky'] ?? false;
1044
        $arguments['failOnWarning']                                   = $arguments['failOnWarning'] ?? false;
1045
        $arguments['groups']                                          = $arguments['groups'] ?? [];
1046
        $arguments['processIsolation']                                = $arguments['processIsolation'] ?? false;
1047
        $arguments['processUncoveredFilesFromWhitelist']              = $arguments['processUncoveredFilesFromWhitelist'] ?? false;
1048
        $arguments['registerMockObjectsFromTestArgumentsRecursively'] = $arguments['registerMockObjectsFromTestArgumentsRecursively'] ?? false;
1049
        $arguments['repeat']                                          = $arguments['repeat'] ?? false;
1050
        $arguments['reportHighLowerBound']                            = $arguments['reportHighLowerBound'] ?? 90;
1051
        $arguments['reportLowUpperBound']                             = $arguments['reportLowUpperBound'] ?? 50;
1052
        $arguments['reportUselessTests']                              = $arguments['reportUselessTests'] ?? true;
1053
        $arguments['reverseList']                                     = $arguments['reverseList'] ?? false;
1054
        $arguments['stopOnError']                                     = $arguments['stopOnError'] ?? false;
1055
        $arguments['stopOnFailure']                                   = $arguments['stopOnFailure'] ?? false;
1056
        $arguments['stopOnIncomplete']                                = $arguments['stopOnIncomplete'] ?? false;
1057
        $arguments['stopOnRisky']                                     = $arguments['stopOnRisky'] ?? false;
1058
        $arguments['stopOnSkipped']                                   = $arguments['stopOnSkipped'] ?? false;
1059
        $arguments['stopOnWarning']                                   = $arguments['stopOnWarning'] ?? false;
1060
        $arguments['strictCoverage']                                  = $arguments['strictCoverage'] ?? false;
1061
        $arguments['testdoxExcludeGroups']                            = $arguments['testdoxExcludeGroups'] ?? [];
1062
        $arguments['testdoxGroups']                                   = $arguments['testdoxGroups'] ?? [];
1063
        $arguments['timeoutForLargeTests']                            = $arguments['timeoutForLargeTests'] ?? 60;
1064
        $arguments['timeoutForMediumTests']                           = $arguments['timeoutForMediumTests'] ?? 10;
1065
        $arguments['timeoutForSmallTests']                            = $arguments['timeoutForSmallTests'] ?? 1;
1066
        $arguments['verbose']                                         = $arguments['verbose'] ?? false;
1067
    }
1068
1069
    /**
1070
     * @param string $type
1071
     * @param string $message
1072
     */
1073
    private function writeMessage($type, $message)
1074
    {
1075
        if (!$this->messagePrinted) {
1076
            $this->write("\n");
1077
        }
1078
1079
        $this->write(
1080
            \sprintf(
1081
                "%-15s%s\n",
1082
                $type . ':',
1083
                $message
1084
            )
1085
        );
1086
1087
        $this->messagePrinted = true;
1088
    }
1089
}
1090