Completed
Push — master ( 01e071...007090 )
by Ehsan
01:46 queued 13s
created

TestSuite::createTest()   F

Complexity

Conditions 28
Paths 1499

Size

Total Lines 172
Code Lines 98

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 28
eloc 98
nc 1499
nop 2
dl 0
loc 172
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
namespace PHPUnit\Framework;
11
12
use Iterator;
13
use IteratorAggregate;
14
use PHPUnit\Runner\BaseTestRunner;
15
use PHPUnit\Runner\Filter\Factory;
16
use PHPUnit\Runner\PhptTestCase;
17
use PHPUnit\Util\Fileloader;
18
use PHPUnit\Util\InvalidArgumentHelper;
19
use RecursiveIteratorIterator;
20
use ReflectionClass;
21
use ReflectionMethod;
22
use Throwable;
23
24
/**
25
 * A TestSuite is a composite of Tests. It runs a collection of test cases.
26
 */
27
class TestSuite implements Test, SelfDescribing, IteratorAggregate
28
{
29
    /**
30
     * Last count of tests in this suite.
31
     *
32
     * @var int|null
33
     */
34
    private $cachedNumTests;
35
36
    /**
37
     * Enable or disable the backup and restoration of the $GLOBALS array.
38
     *
39
     * @var bool
40
     */
41
    protected $backupGlobals;
42
43
    /**
44
     * Enable or disable the backup and restoration of static attributes.
45
     *
46
     * @var bool
47
     */
48
    protected $backupStaticAttributes;
49
50
    /**
51
     * @var bool
52
     */
53
    private $beStrictAboutChangesToGlobalState;
54
55
    /**
56
     * @var bool
57
     */
58
    protected $runTestInSeparateProcess = false;
59
60
    /**
61
     * The name of the test suite.
62
     *
63
     * @var string
64
     */
65
    protected $name = '';
66
67
    /**
68
     * The test groups of the test suite.
69
     *
70
     * @var array
71
     */
72
    protected $groups = [];
73
74
    /**
75
     * The tests in the test suite.
76
     *
77
     * @var array
78
     */
79
    protected $tests = [];
80
81
    /**
82
     * The number of tests in the test suite.
83
     *
84
     * @var int
85
     */
86
    protected $numTests = -1;
87
88
    /**
89
     * @var bool
90
     */
91
    protected $testCase = false;
92
93
    /**
94
     * @var array
95
     */
96
    protected $foundClasses = [];
97
98
    /**
99
     * @var Factory
100
     */
101
    private $iteratorFilter;
102
103
    /**
104
     * Constructs a new TestSuite:
105
     *
106
     *   - PHPUnit_Framework_TestSuite() constructs an empty TestSuite.
107
     *
108
     *   - PHPUnit_Framework_TestSuite(ReflectionClass) constructs a
109
     *     TestSuite from the given class.
110
     *
111
     *   - PHPUnit_Framework_TestSuite(ReflectionClass, String)
112
     *     constructs a TestSuite from the given class with the given
113
     *     name.
114
     *
115
     *   - PHPUnit_Framework_TestSuite(String) either constructs a
116
     *     TestSuite from the given class (if the passed string is the
117
     *     name of an existing class) or constructs an empty TestSuite
118
     *     with the given name.
119
     *
120
     * @param mixed  $theClass
121
     * @param string $name
122
     *
123
     * @throws Exception
124
     */
125
    public function __construct($theClass = '', $name = '')
126
    {
127
        $argumentsValid = false;
128
129
        if (\is_object($theClass) &&
130
            $theClass instanceof ReflectionClass) {
131
            $argumentsValid = true;
132
        } elseif (\is_string($theClass) &&
133
            $theClass !== '' &&
134
            \class_exists($theClass, false)) {
135
            $argumentsValid = true;
136
137
            if ($name == '') {
138
                $name = $theClass;
139
            }
140
141
            $theClass = new ReflectionClass($theClass);
142
        } elseif (\is_string($theClass)) {
143
            $this->setName($theClass);
144
145
            return;
146
        }
147
148
        if (!$argumentsValid) {
149
            throw new Exception;
150
        }
151
152
        if (!$theClass->isSubclassOf(TestCase::class)) {
153
            throw new Exception(
154
                'Class "' . $theClass->name . '" does not extend PHPUnit\Framework\TestCase.'
155
            );
156
        }
157
158
        if ($name != '') {
159
            $this->setName($name);
160
        } else {
161
            $this->setName($theClass->getName());
162
        }
163
164
        $constructor = $theClass->getConstructor();
165
166
        if ($constructor !== null &&
167
            !$constructor->isPublic()) {
168
            $this->addTest(
169
                self::warning(
170
                    \sprintf(
171
                        'Class "%s" has no public constructor.',
172
                        $theClass->getName()
173
                    )
174
                )
175
            );
176
177
            return;
178
        }
179
180
        foreach ($theClass->getMethods() as $method) {
181
            $this->addTestMethod($theClass, $method);
182
        }
183
184
        if (empty($this->tests)) {
185
            $this->addTest(
186
                self::warning(
187
                    \sprintf(
188
                        'No tests found in class "%s".',
189
                        $theClass->getName()
190
                    )
191
                )
192
            );
193
        }
194
195
        $this->testCase = true;
196
    }
197
198
    /**
199
     * Returns a string representation of the test suite.
200
     *
201
     * @return string
202
     */
203
    public function toString()
204
    {
205
        return $this->getName();
206
    }
207
208
    /**
209
     * Adds a test to the suite.
210
     *
211
     * @param Test  $test
212
     * @param array $groups
213
     */
214
    public function addTest(Test $test, $groups = [])
215
    {
216
        $class = new ReflectionClass($test);
217
218
        if (!$class->isAbstract()) {
219
            $this->tests[]  = $test;
220
            $this->numTests = -1;
221
222
            if ($test instanceof self && empty($groups)) {
223
                $groups = $test->getGroups();
224
            }
225
226
            if (empty($groups)) {
227
                $groups = ['default'];
228
            }
229
230
            foreach ($groups as $group) {
231
                if (!isset($this->groups[$group])) {
232
                    $this->groups[$group] = [$test];
233
                } else {
234
                    $this->groups[$group][] = $test;
235
                }
236
            }
237
238
            if ($test instanceof TestCase) {
239
                $test->setGroups($groups);
240
            }
241
        }
242
    }
243
244
    /**
245
     * Adds the tests from the given class to the suite.
246
     *
247
     * @param mixed $testClass
248
     *
249
     * @throws Exception
250
     */
251
    public function addTestSuite($testClass)
252
    {
253
        if (\is_string($testClass) && \class_exists($testClass)) {
254
            $testClass = new ReflectionClass($testClass);
255
        }
256
257
        if (!\is_object($testClass)) {
258
            throw InvalidArgumentHelper::factory(
259
                1,
260
                'class name or object'
261
            );
262
        }
263
264
        if ($testClass instanceof self) {
265
            $this->addTest($testClass);
266
        } elseif ($testClass instanceof ReflectionClass) {
267
            $suiteMethod = false;
268
269
            if (!$testClass->isAbstract()) {
270
                if ($testClass->hasMethod(BaseTestRunner::SUITE_METHODNAME)) {
271
                    $method = $testClass->getMethod(
272
                        BaseTestRunner::SUITE_METHODNAME
273
                    );
274
275
                    if ($method->isStatic()) {
276
                        $this->addTest(
277
                            $method->invoke(null, $testClass->getName())
278
                        );
279
280
                        $suiteMethod = true;
281
                    }
282
                }
283
            }
284
285
            if (!$suiteMethod && !$testClass->isAbstract()) {
286
                $this->addTest(new self($testClass));
287
            }
288
        } else {
289
            throw new Exception;
290
        }
291
    }
292
293
    /**
294
     * Wraps both <code>addTest()</code> and <code>addTestSuite</code>
295
     * as well as the separate import statements for the user's convenience.
296
     *
297
     * If the named file cannot be read or there are no new tests that can be
298
     * added, a <code>PHPUnit_Framework_WarningTestCase</code> will be created instead,
299
     * leaving the current test run untouched.
300
     *
301
     * @param string $filename
302
     *
303
     * @throws Exception
304
     */
305
    public function addTestFile($filename)
306
    {
307
        if (!\is_string($filename)) {
308
            throw InvalidArgumentHelper::factory(1, 'string');
309
        }
310
311
        if (\file_exists($filename) && \substr($filename, -5) == '.phpt') {
312
            $this->addTest(
313
                new PhptTestCase($filename)
314
            );
315
316
            return;
317
        }
318
319
        // The given file may contain further stub classes in addition to the
320
        // test class itself. Figure out the actual test class.
321
        $classes    = \get_declared_classes();
322
        $filename   = Fileloader::checkAndLoad($filename);
323
        $newClasses = \array_diff(\get_declared_classes(), $classes);
324
325
        // The diff is empty in case a parent class (with test methods) is added
326
        // AFTER a child class that inherited from it. To account for that case,
327
        // cumulate all discovered classes, so the parent class may be found in
328
        // a later invocation.
329
        if (!empty($newClasses)) {
330
            // On the assumption that test classes are defined first in files,
331
            // process discovered classes in approximate LIFO order, so as to
332
            // avoid unnecessary reflection.
333
            $this->foundClasses = \array_merge($newClasses, $this->foundClasses);
334
        }
335
336
        // The test class's name must match the filename, either in full, or as
337
        // a PEAR/PSR-0 prefixed shortname ('NameSpace_ShortName'), or as a
338
        // PSR-1 local shortname ('NameSpace\ShortName'). The comparison must be
339
        // anchored to prevent false-positive matches (e.g., 'OtherShortName').
340
        $shortname      = \basename($filename, '.php');
341
        $shortnameRegEx = '/(?:^|_|\\\\)' . \preg_quote($shortname, '/') . '$/';
342
343
        foreach ($this->foundClasses as $i => $className) {
344
            if (\preg_match($shortnameRegEx, $className)) {
345
                $class = new ReflectionClass($className);
346
347
                if ($class->getFileName() == $filename) {
348
                    $newClasses = [$className];
349
                    unset($this->foundClasses[$i]);
350
                    break;
351
                }
352
            }
353
        }
354
355
        foreach ($newClasses as $className) {
356
            $class = new ReflectionClass($className);
357
358
            if (!$class->isAbstract()) {
359
                if ($class->hasMethod(BaseTestRunner::SUITE_METHODNAME)) {
360
                    $method = $class->getMethod(
361
                        BaseTestRunner::SUITE_METHODNAME
362
                    );
363
364
                    if ($method->isStatic()) {
365
                        $this->addTest($method->invoke(null, $className));
366
                    }
367
                } elseif ($class->implementsInterface(Test::class)) {
368
                    $this->addTestSuite($class);
369
                }
370
            }
371
        }
372
373
        $this->numTests = -1;
374
    }
375
376
    /**
377
     * Wrapper for addTestFile() that adds multiple test files.
378
     *
379
     * @param array|Iterator $filenames
380
     *
381
     * @throws Exception
382
     */
383
    public function addTestFiles($filenames)
384
    {
385
        if (!(\is_array($filenames) ||
386
            (\is_object($filenames) && $filenames instanceof Iterator))) {
387
            throw InvalidArgumentHelper::factory(
388
                1,
389
                'array or iterator'
390
            );
391
        }
392
393
        foreach ($filenames as $filename) {
394
            $this->addTestFile((string) $filename);
395
        }
396
    }
397
398
    /**
399
     * Counts the number of test cases that will be run by this test.
400
     *
401
     * @param bool $preferCache Indicates if cache is preferred.
402
     *
403
     * @return int
404
     */
405
    public function count($preferCache = false)
406
    {
407
        if ($preferCache && $this->cachedNumTests !== null) {
408
            return $this->cachedNumTests;
409
        }
410
411
        $numTests = 0;
412
413
        foreach ($this as $test) {
414
            $numTests += \count($test);
415
        }
416
417
        $this->cachedNumTests = $numTests;
418
419
        return $numTests;
420
    }
421
422
    /**
423
     * @param ReflectionClass $theClass
424
     * @param string          $name
425
     *
426
     * @return Test
427
     *
428
     * @throws Exception
429
     */
430
    public static function createTest(ReflectionClass $theClass, $name)
431
    {
432
        $className = $theClass->getName();
433
434
        if (!$theClass->isInstantiable()) {
435
            return self::warning(
436
                \sprintf('Cannot instantiate class "%s".', $className)
437
            );
438
        }
439
440
        $backupSettings = \PHPUnit\Util\Test::getBackupSettings(
441
            $className,
442
            $name
443
        );
444
445
        $preserveGlobalState = \PHPUnit\Util\Test::getPreserveGlobalStateSettings(
446
            $className,
447
            $name
448
        );
449
450
        $runTestInSeparateProcess = \PHPUnit\Util\Test::getProcessIsolationSettings(
451
            $className,
452
            $name
453
        );
454
455
        $constructor = $theClass->getConstructor();
456
457
        if ($constructor !== null) {
458
            $parameters = $constructor->getParameters();
459
460
            // TestCase() or TestCase($name)
461
            if (\count($parameters) < 2) {
462
                $test = new $className;
463
            } // TestCase($name, $data)
464
            else {
465
                try {
466
                    $data = \PHPUnit\Util\Test::getProvidedData(
467
                        $className,
468
                        $name
469
                    );
470
                } catch (IncompleteTestError $e) {
471
                    $message = \sprintf(
472
                        'Test for %s::%s marked incomplete by data provider',
473
                        $className,
474
                        $name
475
                    );
476
477
                    $_message = $e->getMessage();
478
479
                    if (!empty($_message)) {
480
                        $message .= "\n" . $_message;
481
                    }
482
483
                    $data = self::incompleteTest($className, $name, $message);
484
                } catch (SkippedTestError $e) {
485
                    $message = \sprintf(
486
                        'Test for %s::%s skipped by data provider',
487
                        $className,
488
                        $name
489
                    );
490
491
                    $_message = $e->getMessage();
492
493
                    if (!empty($_message)) {
494
                        $message .= "\n" . $_message;
495
                    }
496
497
                    $data = self::skipTest($className, $name, $message);
498
                } catch (Throwable $_t) {
499
                    $t = $_t;
500
                } catch (Exception $_t) {
501
                    $t = $_t;
502
                }
503
504
                if (isset($t)) {
505
                    $message = \sprintf(
506
                        'The data provider specified for %s::%s is invalid.',
507
                        $className,
508
                        $name
509
                    );
510
511
                    $_message = $t->getMessage();
512
513
                    if (!empty($_message)) {
514
                        $message .= "\n" . $_message;
515
                    }
516
517
                    $data = self::warning($message);
518
                }
519
520
                // Test method with @dataProvider.
521
                if (isset($data)) {
522
                    $test = new DataProviderTestSuite(
523
                        $className . '::' . $name
524
                    );
525
526
                    if (empty($data)) {
527
                        $data = self::warning(
528
                            \sprintf(
529
                                'No tests found in suite "%s".',
530
                                $test->getName()
531
                            )
532
                        );
533
                    }
534
535
                    $groups = \PHPUnit\Util\Test::getGroups($className, $name);
536
537
                    if ($data instanceof WarningTestCase ||
538
                        $data instanceof SkippedTestCase ||
539
                        $data instanceof IncompleteTestCase) {
540
                        $test->addTest($data, $groups);
541
                    } else {
542
                        foreach ($data as $_dataName => $_data) {
543
                            $_test = new $className($name, $_data, $_dataName);
544
545
                            if ($runTestInSeparateProcess) {
546
                                $_test->setRunTestInSeparateProcess(true);
547
548
                                if ($preserveGlobalState !== null) {
549
                                    $_test->setPreserveGlobalState($preserveGlobalState);
550
                                }
551
                            }
552
553
                            if ($backupSettings['backupGlobals'] !== null) {
554
                                $_test->setBackupGlobals(
555
                                    $backupSettings['backupGlobals']
556
                                );
557
                            }
558
559
                            if ($backupSettings['backupStaticAttributes'] !== null) {
560
                                $_test->setBackupStaticAttributes(
561
                                    $backupSettings['backupStaticAttributes']
562
                                );
563
                            }
564
565
                            $test->addTest($_test, $groups);
566
                        }
567
                    }
568
                } else {
569
                    $test = new $className;
570
                }
571
            }
572
        }
573
574
        if (!isset($test)) {
575
            throw new Exception('No valid test provided.');
576
        }
577
578
        if ($test instanceof TestCase) {
579
            $test->setName($name);
580
581
            if ($runTestInSeparateProcess) {
582
                $test->setRunTestInSeparateProcess(true);
583
584
                if ($preserveGlobalState !== null) {
585
                    $test->setPreserveGlobalState($preserveGlobalState);
586
                }
587
            }
588
589
            if ($backupSettings['backupGlobals'] !== null) {
590
                $test->setBackupGlobals($backupSettings['backupGlobals']);
591
            }
592
593
            if ($backupSettings['backupStaticAttributes'] !== null) {
594
                $test->setBackupStaticAttributes(
595
                    $backupSettings['backupStaticAttributes']
596
                );
597
            }
598
        }
599
600
        return $test;
601
    }
602
603
    /**
604
     * Creates a default TestResult object.
605
     *
606
     * @return TestResult
607
     */
608
    protected function createResult()
609
    {
610
        return new TestResult;
611
    }
612
613
    /**
614
     * Returns the name of the suite.
615
     *
616
     * @return string
617
     */
618
    public function getName()
619
    {
620
        return $this->name;
621
    }
622
623
    /**
624
     * Returns the test groups of the suite.
625
     *
626
     * @return array
627
     */
628
    public function getGroups()
629
    {
630
        return \array_keys($this->groups);
631
    }
632
633
    public function getGroupDetails()
634
    {
635
        return $this->groups;
636
    }
637
638
    /**
639
     * Set tests groups of the test case
640
     *
641
     * @param array $groups
642
     */
643
    public function setGroupDetails(array $groups)
644
    {
645
        $this->groups = $groups;
646
    }
647
648
    /**
649
     * Runs the tests and collects their result in a TestResult.
650
     *
651
     * @param TestResult $result
652
     *
653
     * @return TestResult
654
     */
655
    public function run(TestResult $result = null)
656
    {
657
        if ($result === null) {
658
            $result = $this->createResult();
659
        }
660
661
        if (\count($this) == 0) {
662
            return $result;
663
        }
664
665
        $hookMethods = \PHPUnit\Util\Test::getHookMethods($this->name);
666
667
        $result->startTestSuite($this);
668
669
        try {
670
            $this->setUp();
671
672
            foreach ($hookMethods['beforeClass'] as $beforeClassMethod) {
673
                if ($this->testCase === true &&
674
                    \class_exists($this->name, false) &&
675
                    \method_exists($this->name, $beforeClassMethod)) {
676
                    if ($missingRequirements = \PHPUnit\Util\Test::getMissingRequirements($this->name, $beforeClassMethod)) {
677
                        $this->markTestSuiteSkipped(\implode(PHP_EOL, $missingRequirements));
678
                    }
679
680
                    \call_user_func([$this->name, $beforeClassMethod]);
681
                }
682
            }
683
        } catch (SkippedTestSuiteError $e) {
684
            $numTests = \count($this);
685
686
            for ($i = 0; $i < $numTests; $i++) {
687
                $result->startTest($this);
688
                $result->addFailure($this, $e, 0);
689
                $result->endTest($this, 0);
690
            }
691
692
            $this->tearDown();
693
            $result->endTestSuite($this);
694
695
            return $result;
696
        } catch (Throwable $_t) {
697
            $t = $_t;
698
        } catch (Exception $_t) {
699
            $t = $_t;
700
        }
701
702
        if (isset($t)) {
703
            $numTests = \count($this);
704
705
            for ($i = 0; $i < $numTests; $i++) {
706
                if ($result->shouldStop()) {
707
                    break;
708
                }
709
710
                $result->startTest($this);
711
                $result->addError($this, $t, 0);
712
                $result->endTest($this, 0);
713
            }
714
715
            $this->tearDown();
716
            $result->endTestSuite($this);
717
718
            return $result;
719
        }
720
721
        foreach ($this as $test) {
722
            if ($result->shouldStop()) {
723
                break;
724
            }
725
726
            if ($test instanceof TestCase || $test instanceof self) {
727
                $test->setbeStrictAboutChangesToGlobalState($this->beStrictAboutChangesToGlobalState);
728
                $test->setBackupGlobals($this->backupGlobals);
729
                $test->setBackupStaticAttributes($this->backupStaticAttributes);
730
                $test->setRunTestInSeparateProcess($this->runTestInSeparateProcess);
731
            }
732
733
            $test->run($result);
734
        }
735
736
        foreach ($hookMethods['afterClass'] as $afterClassMethod) {
737
            if ($this->testCase === true && \class_exists($this->name, false) && \method_exists($this->name, $afterClassMethod)) {
738
                \call_user_func([$this->name, $afterClassMethod]);
739
            }
740
        }
741
742
        $this->tearDown();
743
744
        $result->endTestSuite($this);
745
746
        return $result;
747
    }
748
749
    /**
750
     * @param bool $runTestInSeparateProcess
751
     *
752
     * @throws Exception
753
     */
754
    public function setRunTestInSeparateProcess($runTestInSeparateProcess)
755
    {
756
        if (\is_bool($runTestInSeparateProcess)) {
757
            $this->runTestInSeparateProcess = $runTestInSeparateProcess;
758
        } else {
759
            throw InvalidArgumentHelper::factory(1, 'boolean');
760
        }
761
    }
762
763
    /**
764
     * Runs a test.
765
     *
766
     * @deprecated
767
     *
768
     * @param Test       $test
769
     * @param TestResult $result
770
     */
771
    public function runTest(Test $test, TestResult $result)
772
    {
773
        $test->run($result);
774
    }
775
776
    /**
777
     * Sets the name of the suite.
778
     *
779
     * @param  string
780
     */
781
    public function setName($name)
782
    {
783
        $this->name = $name;
784
    }
785
786
    /**
787
     * Returns the test at the given index.
788
     *
789
     * @param  int|false
790
     *
791
     * @return Test
792
     */
793
    public function testAt($index)
794
    {
795
        if (isset($this->tests[$index])) {
796
            return $this->tests[$index];
797
        }
798
799
        return false;
800
    }
801
802
    /**
803
     * Returns the tests as an enumeration.
804
     *
805
     * @return array
806
     */
807
    public function tests()
808
    {
809
        return $this->tests;
810
    }
811
812
    /**
813
     * Set tests of the test suite
814
     *
815
     * @param array $tests
816
     */
817
    public function setTests(array $tests)
818
    {
819
        $this->tests = $tests;
820
    }
821
822
    /**
823
     * Mark the test suite as skipped.
824
     *
825
     * @param string $message
826
     *
827
     * @throws SkippedTestSuiteError
828
     */
829
    public function markTestSuiteSkipped($message = '')
830
    {
831
        throw new SkippedTestSuiteError($message);
832
    }
833
834
    /**
835
     * @param ReflectionClass  $class
836
     * @param ReflectionMethod $method
837
     */
838
    protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method)
839
    {
840
        if (!$this->isTestMethod($method)) {
841
            return;
842
        }
843
844
        $name = $method->getName();
845
846
        if (!$method->isPublic()) {
847
            $this->addTest(
848
                self::warning(
849
                    \sprintf(
850
                        'Test method "%s" in test class "%s" is not public.',
851
                        $name,
852
                        $class->getName()
853
                    )
854
                )
855
            );
856
857
            return;
858
        }
859
860
        $test = self::createTest($class, $name);
861
862
        if ($test instanceof TestCase || $test instanceof DataProviderTestSuite) {
863
            $test->setDependencies(
864
                \PHPUnit\Util\Test::getDependencies($class->getName(), $name)
865
            );
866
        }
867
868
        $this->addTest(
869
            $test,
870
            \PHPUnit\Util\Test::getGroups($class->getName(), $name)
871
        );
872
    }
873
874
    /**
875
     * @param ReflectionMethod $method
876
     *
877
     * @return bool
878
     */
879
    public static function isTestMethod(ReflectionMethod $method)
880
    {
881
        if (\strpos($method->name, 'test') === 0) {
882
            return true;
883
        }
884
885
        // @scenario on TestCase::testMethod()
886
        // @test     on TestCase::testMethod()
887
        $docComment = $method->getDocComment();
888
889
        return \strpos($docComment, '@test') !== false ||
890
            \strpos($docComment, '@scenario') !== false;
891
    }
892
893
    /**
894
     * @param string $message
895
     *
896
     * @return WarningTestCase
897
     */
898
    protected static function warning($message)
899
    {
900
        return new WarningTestCase($message);
901
    }
902
903
    /**
904
     * @param string $class
905
     * @param string $methodName
906
     * @param string $message
907
     *
908
     * @return SkippedTestCase
909
     */
910
    protected static function skipTest($class, $methodName, $message)
911
    {
912
        return new SkippedTestCase($class, $methodName, $message);
913
    }
914
915
    /**
916
     * @param string $class
917
     * @param string $methodName
918
     * @param string $message
919
     *
920
     * @return IncompleteTestCase
921
     */
922
    protected static function incompleteTest($class, $methodName, $message)
923
    {
924
        return new IncompleteTestCase($class, $methodName, $message);
925
    }
926
927
    /**
928
     * @param bool $beStrictAboutChangesToGlobalState
929
     */
930
    public function setbeStrictAboutChangesToGlobalState($beStrictAboutChangesToGlobalState)
931
    {
932
        if (\is_null($this->beStrictAboutChangesToGlobalState) && \is_bool($beStrictAboutChangesToGlobalState)) {
933
            $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState;
934
        }
935
    }
936
937
    /**
938
     * @param bool $backupGlobals
939
     */
940
    public function setBackupGlobals($backupGlobals)
941
    {
942
        if (\is_null($this->backupGlobals) && \is_bool($backupGlobals)) {
943
            $this->backupGlobals = $backupGlobals;
944
        }
945
    }
946
947
    /**
948
     * @param bool $backupStaticAttributes
949
     */
950
    public function setBackupStaticAttributes($backupStaticAttributes)
951
    {
952
        if (\is_null($this->backupStaticAttributes) && \is_bool($backupStaticAttributes)) {
953
            $this->backupStaticAttributes = $backupStaticAttributes;
954
        }
955
    }
956
957
    /**
958
     * Returns an iterator for this test suite.
959
     *
960
     * @return RecursiveIteratorIterator
961
     */
962
    public function getIterator()
963
    {
964
        $iterator = new TestSuiteIterator($this);
965
966
        if ($this->iteratorFilter !== null) {
967
            $iterator = $this->iteratorFilter->factory($iterator, $this);
968
        }
969
970
        return $iterator;
971
    }
972
973
    public function injectFilter(Factory $filter)
974
    {
975
        $this->iteratorFilter = $filter;
976
        foreach ($this as $test) {
977
            if ($test instanceof self) {
978
                $test->injectFilter($filter);
979
            }
980
        }
981
    }
982
983
    /**
984
     * Template Method that is called before the tests
985
     * of this test suite are run.
986
     */
987
    protected function setUp()
988
    {
989
    }
990
991
    /**
992
     * Template Method that is called after the tests
993
     * of this test suite have finished running.
994
     */
995
    protected function tearDown()
996
    {
997
    }
998
}
999