~ubuntu-branches/ubuntu/natty/phpunit/natty

« back to all changes in this revision

Viewing changes to PHPUnit-3.5.5/PHPUnit/Framework/TestSuite.php

  • Committer: Package Import Robot
  • Author(s): Ivan Borzenkov
  • Date: 2010-12-11 18:19:39 UTC
  • mfrom: (0.11.1) (1.5.3) (12.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20101211181939-8650nbu08hf2z9v1
Tags: 3.5.5-2
fix doc-base-file-references-missing-file

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * PHPUnit
 
4
 *
 
5
 * Copyright (c) 2002-2010, Sebastian Bergmann <sebastian@phpunit.de>.
 
6
 * All rights reserved.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted provided that the following conditions
 
10
 * are met:
 
11
 *
 
12
 *   * Redistributions of source code must retain the above copyright
 
13
 *     notice, this list of conditions and the following disclaimer.
 
14
 *
 
15
 *   * Redistributions in binary form must reproduce the above copyright
 
16
 *     notice, this list of conditions and the following disclaimer in
 
17
 *     the documentation and/or other materials provided with the
 
18
 *     distribution.
 
19
 *
 
20
 *   * Neither the name of Sebastian Bergmann nor the names of his
 
21
 *     contributors may be used to endorse or promote products derived
 
22
 *     from this software without specific prior written permission.
 
23
 *
 
24
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
25
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
26
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 
27
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 
28
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 
29
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 
30
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
31
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 
32
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
33
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 
34
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
35
 * POSSIBILITY OF SUCH DAMAGE.
 
36
 *
 
37
 * @package    PHPUnit
 
38
 * @subpackage Framework
 
39
 * @author     Sebastian Bergmann <sebastian@phpunit.de>
 
40
 * @copyright  2002-2010 Sebastian Bergmann <sebastian@phpunit.de>
 
41
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
 
42
 * @link       http://www.phpunit.de/
 
43
 * @since      File available since Release 2.0.0
 
44
 */
 
45
 
 
46
require_once 'PHP/CodeCoverage.php';
 
47
 
 
48
/**
 
49
 * A TestSuite is a composite of Tests. It runs a collection of test cases.
 
50
 *
 
51
 * Here is an example using the dynamic test definition.
 
52
 *
 
53
 * <code>
 
54
 * <?php
 
55
 * $suite = new PHPUnit_Framework_TestSuite;
 
56
 * $suite->addTest(new MathTest('testPass'));
 
57
 * ?>
 
58
 * </code>
 
59
 *
 
60
 * Alternatively, a TestSuite can extract the tests to be run automatically.
 
61
 * To do so you pass a ReflectionClass instance for your
 
62
 * PHPUnit_Framework_TestCase class to the PHPUnit_Framework_TestSuite
 
63
 * constructor.
 
64
 *
 
65
 * <code>
 
66
 * <?php
 
67
 * $suite = new PHPUnit_Framework_TestSuite(
 
68
 *   new ReflectionClass('MathTest')
 
69
 * );
 
70
 * ?>
 
71
 * </code>
 
72
 *
 
73
 * This constructor creates a suite with all the methods starting with
 
74
 * "test" that take no arguments.
 
75
 *
 
76
 * @package    PHPUnit
 
77
 * @subpackage Framework
 
78
 * @author     Sebastian Bergmann <sebastian@phpunit.de>
 
79
 * @copyright  2002-2010 Sebastian Bergmann <sebastian@phpunit.de>
 
80
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
 
81
 * @version    Release: 3.5.5
 
82
 * @link       http://www.phpunit.de/
 
83
 * @since      Class available since Release 2.0.0
 
84
 */
 
85
class PHPUnit_Framework_TestSuite implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing, IteratorAggregate
 
86
{
 
87
    /**
 
88
     * Enable or disable the backup and restoration of the $GLOBALS array.
 
89
     *
 
90
     * @var    boolean
 
91
     */
 
92
    protected $backupGlobals = NULL;
 
93
 
 
94
    /**
 
95
     * Enable or disable the backup and restoration of static attributes.
 
96
     *
 
97
     * @var    boolean
 
98
     */
 
99
    protected $backupStaticAttributes = NULL;
 
100
 
 
101
    /**
 
102
     * The name of the test suite.
 
103
     *
 
104
     * @var    string
 
105
     */
 
106
    protected $name = '';
 
107
 
 
108
    /**
 
109
     * The test groups of the test suite.
 
110
     *
 
111
     * @var    array
 
112
     */
 
113
    protected $groups = array();
 
114
 
 
115
    /**
 
116
     * The tests in the test suite.
 
117
     *
 
118
     * @var    array
 
119
     */
 
120
    protected $tests = array();
 
121
 
 
122
    /**
 
123
     * The number of tests in the test suite.
 
124
     *
 
125
     * @var    integer
 
126
     */
 
127
    protected $numTests = -1;
 
128
 
 
129
    /**
 
130
     * @var boolean
 
131
     */
 
132
    protected $testCase = FALSE;
 
133
 
 
134
    /**
 
135
     * Constructs a new TestSuite:
 
136
     *
 
137
     *   - PHPUnit_Framework_TestSuite() constructs an empty TestSuite.
 
138
     *
 
139
     *   - PHPUnit_Framework_TestSuite(ReflectionClass) constructs a
 
140
     *     TestSuite from the given class.
 
141
     *
 
142
     *   - PHPUnit_Framework_TestSuite(ReflectionClass, String)
 
143
     *     constructs a TestSuite from the given class with the given
 
144
     *     name.
 
145
     *
 
146
     *   - PHPUnit_Framework_TestSuite(String) either constructs a
 
147
     *     TestSuite from the given class (if the passed string is the
 
148
     *     name of an existing class) or constructs an empty TestSuite
 
149
     *     with the given name.
 
150
     *
 
151
     * @param  mixed  $theClass
 
152
     * @param  string $name
 
153
     * @throws InvalidArgumentException
 
154
     */
 
155
    public function __construct($theClass = '', $name = '')
 
156
    {
 
157
        $argumentsValid = FALSE;
 
158
 
 
159
        if (is_object($theClass) &&
 
160
            $theClass instanceof ReflectionClass) {
 
161
            $argumentsValid = TRUE;
 
162
        }
 
163
 
 
164
        else if (is_string($theClass) &&
 
165
                 $theClass !== '' &&
 
166
                 class_exists($theClass, FALSE)) {
 
167
            $argumentsValid = TRUE;
 
168
 
 
169
            if ($name == '') {
 
170
                $name = $theClass;
 
171
            }
 
172
 
 
173
            $theClass = new ReflectionClass($theClass);
 
174
        }
 
175
 
 
176
        else if (is_string($theClass)) {
 
177
            $this->setName($theClass);
 
178
            return;
 
179
        }
 
180
 
 
181
        if (!$argumentsValid) {
 
182
            throw new InvalidArgumentException;
 
183
        }
 
184
 
 
185
        if (!$theClass->isSubclassOf('PHPUnit_Framework_TestCase')) {
 
186
            throw new InvalidArgumentException(
 
187
              'Class does not extend PHPUnit_Framework_TestCase.'
 
188
            );
 
189
        }
 
190
 
 
191
        $filename = $theClass->getFilename();
 
192
 
 
193
        if (strpos($filename, 'eval()') === FALSE) {
 
194
            PHP_CodeCoverage::getInstance()->filter()->addFileToBlacklist(
 
195
              realpath($filename), 'TESTS'
 
196
            );
 
197
        }
 
198
 
 
199
        if ($name != '') {
 
200
            $this->setName($name);
 
201
        } else {
 
202
            $this->setName($theClass->getName());
 
203
        }
 
204
 
 
205
        $constructor = $theClass->getConstructor();
 
206
 
 
207
        if ($constructor !== NULL &&
 
208
            !$constructor->isPublic()) {
 
209
            $this->addTest(
 
210
              self::warning(
 
211
                sprintf(
 
212
                  'Class "%s" has no public constructor.',
 
213
 
 
214
                  $theClass->getName()
 
215
                )
 
216
              )
 
217
            );
 
218
 
 
219
            return;
 
220
        }
 
221
 
 
222
        foreach ($theClass->getMethods() as $method) {
 
223
            if (strpos($method->getDeclaringClass()->getName(), 'PHPUnit_') !== 0) {
 
224
                $this->addTestMethod($theClass, $method);
 
225
            }
 
226
        }
 
227
 
 
228
        if (empty($this->tests)) {
 
229
            $this->addTest(
 
230
              self::warning(
 
231
                sprintf(
 
232
                  'No tests found in class "%s".',
 
233
 
 
234
                  $theClass->getName()
 
235
                )
 
236
              )
 
237
            );
 
238
        }
 
239
 
 
240
        $this->testCase = TRUE;
 
241
    }
 
242
 
 
243
    /**
 
244
     * Returns a string representation of the test suite.
 
245
     *
 
246
     * @return string
 
247
     */
 
248
    public function toString()
 
249
    {
 
250
        return $this->getName();
 
251
    }
 
252
 
 
253
    /**
 
254
     * Adds a test to the suite.
 
255
     *
 
256
     * @param  PHPUnit_Framework_Test $test
 
257
     * @param  array                  $groups
 
258
     */
 
259
    public function addTest(PHPUnit_Framework_Test $test, $groups = array())
 
260
    {
 
261
        $class = new ReflectionClass($test);
 
262
 
 
263
        if (!$class->isAbstract()) {
 
264
            $this->tests[]  = $test;
 
265
            $this->numTests = -1;
 
266
 
 
267
            if ($test instanceof PHPUnit_Framework_TestSuite &&
 
268
                empty($groups)) {
 
269
                $groups = $test->getGroups();
 
270
            }
 
271
 
 
272
            if (empty($groups)) {
 
273
                $groups = array('__nogroup__');
 
274
            }
 
275
 
 
276
            foreach ($groups as $group) {
 
277
                if (!isset($this->groups[$group])) {
 
278
                    $this->groups[$group] = array($test);
 
279
                } else {
 
280
                    $this->groups[$group][] = $test;
 
281
                }
 
282
            }
 
283
        }
 
284
    }
 
285
 
 
286
    /**
 
287
     * Adds the tests from the given class to the suite.
 
288
     *
 
289
     * @param  mixed $testClass
 
290
     * @throws InvalidArgumentException
 
291
     */
 
292
    public function addTestSuite($testClass)
 
293
    {
 
294
        if (is_string($testClass) && class_exists($testClass)) {
 
295
            $testClass = new ReflectionClass($testClass);
 
296
        }
 
297
 
 
298
        if (!is_object($testClass)) {
 
299
            throw PHPUnit_Util_InvalidArgumentHelper::factory(
 
300
              1, 'class name or object'
 
301
            );
 
302
        }
 
303
 
 
304
        if ($testClass instanceof PHPUnit_Framework_TestSuite) {
 
305
            $this->addTest($testClass);
 
306
        }
 
307
 
 
308
        else if ($testClass instanceof ReflectionClass) {
 
309
            $suiteMethod = FALSE;
 
310
 
 
311
            if (!$testClass->isAbstract()) {
 
312
                if ($testClass->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) {
 
313
                    $method = $testClass->getMethod(
 
314
                      PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME
 
315
                    );
 
316
 
 
317
                    if ($method->isStatic()) {
 
318
                        $this->addTest(
 
319
                          $method->invoke(NULL, $testClass->getName())
 
320
                        );
 
321
 
 
322
                        $suiteMethod = TRUE;
 
323
                    }
 
324
                }
 
325
            }
 
326
 
 
327
            if (!$suiteMethod && !$testClass->isAbstract()) {
 
328
                $this->addTest(new PHPUnit_Framework_TestSuite($testClass));
 
329
            }
 
330
        }
 
331
 
 
332
        else {
 
333
            throw new InvalidArgumentException;
 
334
        }
 
335
    }
 
336
 
 
337
    /**
 
338
     * Wraps both <code>addTest()</code> and <code>addTestSuite</code>
 
339
     * as well as the separate import statements for the user's convenience.
 
340
     *
 
341
     * If the named file cannot be read or there are no new tests that can be
 
342
     * added, a <code>PHPUnit_Framework_Warning</code> will be created instead,
 
343
     * leaving the current test run untouched.
 
344
     *
 
345
     * @param  string  $filename
 
346
     * @param  boolean $syntaxCheck
 
347
     * @param  array   $phptOptions Array with ini settings for the php instance
 
348
     *                              run, key being the name if the setting,
 
349
     *                              value the ini value.
 
350
     * @throws InvalidArgumentException
 
351
     * @since  Method available since Release 2.3.0
 
352
     * @author Stefano F. Rausch <stefano@rausch-e.net>
 
353
     */
 
354
    public function addTestFile($filename, $syntaxCheck = FALSE, $phptOptions = array())
 
355
    {
 
356
        if (!is_string($filename)) {
 
357
            throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
 
358
        }
 
359
 
 
360
        if (file_exists($filename) && substr($filename, -5) == '.phpt') {
 
361
            $this->addTest(
 
362
              new PHPUnit_Extensions_PhptTestCase($filename, $phptOptions)
 
363
            );
 
364
 
 
365
            return;
 
366
        }
 
367
 
 
368
        if (!file_exists($filename)) {
 
369
            $includePaths = explode(PATH_SEPARATOR, get_include_path());
 
370
 
 
371
            foreach ($includePaths as $includePath) {
 
372
                $file = $includePath . DIRECTORY_SEPARATOR . $filename;
 
373
 
 
374
                if (file_exists($file)) {
 
375
                    $filename = $file;
 
376
                    break;
 
377
                }
 
378
            }
 
379
        }
 
380
 
 
381
        PHPUnit_Util_Class::collectStart();
 
382
        PHPUnit_Util_Fileloader::checkAndLoad($filename, $syntaxCheck);
 
383
        $newClasses = PHPUnit_Util_Class::collectEnd();
 
384
        $baseName   = str_replace('.php', '', basename($filename));
 
385
 
 
386
        foreach ($newClasses as $className) {
 
387
            if (substr($className, 0 - strlen($baseName)) == $baseName) {
 
388
                $newClasses = array($className);
 
389
                break;
 
390
            }
 
391
        }
 
392
 
 
393
        $testsFound = FALSE;
 
394
 
 
395
        foreach ($newClasses as $className) {
 
396
            $class = new ReflectionClass($className);
 
397
 
 
398
            if (!$class->isAbstract()) {
 
399
                if ($class->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) {
 
400
                    $method = $class->getMethod(
 
401
                      PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME
 
402
                    );
 
403
 
 
404
                    if ($method->isStatic()) {
 
405
                        $this->addTest($method->invoke(NULL, $className));
 
406
 
 
407
                        $testsFound = TRUE;
 
408
                    }
 
409
                }
 
410
 
 
411
                else if ($class->implementsInterface('PHPUnit_Framework_Test')) {
 
412
                    $this->addTestSuite($class);
 
413
 
 
414
                    $testsFound = TRUE;
 
415
                }
 
416
            }
 
417
        }
 
418
 
 
419
        $this->numTests = -1;
 
420
    }
 
421
 
 
422
    /**
 
423
     * Wrapper for addTestFile() that adds multiple test files.
 
424
     *
 
425
     * @param  array|Iterator $filenames
 
426
     * @throws InvalidArgumentException
 
427
     * @since  Method available since Release 2.3.0
 
428
     */
 
429
    public function addTestFiles($filenames, $syntaxCheck = FALSE)
 
430
    {
 
431
        if (!(is_array($filenames) ||
 
432
             (is_object($filenames) && $filenames instanceof Iterator))) {
 
433
            throw PHPUnit_Util_InvalidArgumentHelper::factory(
 
434
              1, 'array or iterator'
 
435
            );
 
436
        }
 
437
 
 
438
        foreach ($filenames as $filename) {
 
439
            $this->addTestFile((string)$filename, $syntaxCheck);
 
440
        }
 
441
    }
 
442
 
 
443
    /**
 
444
     * Counts the number of test cases that will be run by this test.
 
445
     *
 
446
     * @return integer
 
447
     */
 
448
    public function count()
 
449
    {
 
450
        if ($this->numTests > -1) {
 
451
            return $this->numTests;
 
452
        }
 
453
 
 
454
        $this->numTests = 0;
 
455
 
 
456
        foreach ($this->tests as $test) {
 
457
            $this->numTests += count($test);
 
458
        }
 
459
 
 
460
        return $this->numTests;
 
461
    }
 
462
 
 
463
    /**
 
464
     * @param  ReflectionClass $theClass
 
465
     * @param  string          $name
 
466
     * @return PHPUnit_Framework_Test
 
467
     * @throws RuntimeException
 
468
     */
 
469
    public static function createTest(ReflectionClass $theClass, $name)
 
470
    {
 
471
        $className = $theClass->getName();
 
472
 
 
473
        if (!$theClass->isInstantiable()) {
 
474
            return self::warning(
 
475
              sprintf('Cannot instantiate class "%s".', $className)
 
476
            );
 
477
        }
 
478
 
 
479
        $backupSettings           = PHPUnit_Util_Test::getBackupSettings(
 
480
                                      $className, $name
 
481
                                    );
 
482
        $preserveGlobalState      = PHPUnit_Util_Test::getPreserveGlobalStateSettings(
 
483
                                      $className, $name
 
484
                                    );
 
485
        $runTestInSeparateProcess = PHPUnit_Util_Test::getProcessIsolationSettings(
 
486
                                      $className, $name
 
487
                                    );
 
488
 
 
489
        $constructor = $theClass->getConstructor();
 
490
 
 
491
        if ($constructor !== NULL) {
 
492
            $parameters = $constructor->getParameters();
 
493
 
 
494
            // TestCase() or TestCase($name)
 
495
            if (count($parameters) < 2) {
 
496
                $test = new $className;
 
497
            }
 
498
 
 
499
            // TestCase($name, $data)
 
500
            else {
 
501
                try {
 
502
                    $data = PHPUnit_Util_Test::getProvidedData(
 
503
                      $className, $name
 
504
                    );
 
505
                }
 
506
 
 
507
                catch (Exception $e) {
 
508
                    $message = sprintf(
 
509
                      'The data provider specified for %s::%s is invalid.',
 
510
                      $className,
 
511
                      $name
 
512
                    );
 
513
 
 
514
                    $_message = $e->getMessage();
 
515
 
 
516
                    if (!empty($_message)) {
 
517
                        $message .= "\n" . $_message;
 
518
                    }
 
519
 
 
520
                    $data = self::warning($message);
 
521
                }
 
522
 
 
523
                // Test method with @dataProvider.
 
524
                if (isset($data)) {
 
525
                    $test = new PHPUnit_Framework_TestSuite_DataProvider(
 
526
                      $className . '::' . $name
 
527
                    );
 
528
 
 
529
                    if (empty($data)) {
 
530
                        $data = self::warning(
 
531
                          sprintf(
 
532
                            'No tests found in suite "%s".',
 
533
                            $test->getName()
 
534
                          )
 
535
                        );
 
536
                    }
 
537
 
 
538
                    if ($data instanceof PHPUnit_Framework_Warning) {
 
539
                        $test->addTest($data);
 
540
                    }
 
541
 
 
542
                    else {
 
543
                        $groups = PHPUnit_Util_Test::getGroups($className, $name);
 
544
 
 
545
                        foreach ($data as $_dataName => $_data) {
 
546
                            $_test = new $className($name, $_data, $_dataName);
 
547
 
 
548
                            if ($runTestInSeparateProcess) {
 
549
                                $_test->setRunTestInSeparateProcess(TRUE);
 
550
 
 
551
                                if ($preserveGlobalState !== NULL) {
 
552
                                    $_test->setPreserveGlobalState($preserveGlobalState);
 
553
                                }
 
554
                            }
 
555
 
 
556
                            if ($backupSettings['backupGlobals'] !== NULL) {
 
557
                                $_test->setBackupGlobals(
 
558
                                  $backupSettings['backupGlobals']
 
559
                                );
 
560
                            }
 
561
 
 
562
                            if ($backupSettings['backupStaticAttributes'] !== NULL) {
 
563
                                $_test->setBackupStaticAttributes(
 
564
                                  $backupSettings['backupStaticAttributes']
 
565
                                );
 
566
                            }
 
567
 
 
568
                            $test->addTest($_test, $groups);
 
569
                        }
 
570
                    }
 
571
                }
 
572
 
 
573
                else {
 
574
                    $test = new $className;
 
575
                }
 
576
            }
 
577
        }
 
578
 
 
579
        if (!isset($test)) {
 
580
            throw new RuntimeException('No valid test provided.');
 
581
        }
 
582
 
 
583
        if ($test instanceof PHPUnit_Framework_TestCase) {
 
584
            $test->setName($name);
 
585
 
 
586
            if ($runTestInSeparateProcess) {
 
587
                $test->setRunTestInSeparateProcess(TRUE);
 
588
 
 
589
                if ($preserveGlobalState !== NULL) {
 
590
                    $test->setPreserveGlobalState($preserveGlobalState);
 
591
                }
 
592
            }
 
593
 
 
594
            if ($backupSettings['backupGlobals'] !== NULL) {
 
595
                $test->setBackupGlobals($backupSettings['backupGlobals']);
 
596
            }
 
597
 
 
598
            if ($backupSettings['backupStaticAttributes'] !== NULL) {
 
599
                $test->setBackupStaticAttributes(
 
600
                  $backupSettings['backupStaticAttributes']
 
601
                );
 
602
            }
 
603
        }
 
604
 
 
605
        return $test;
 
606
    }
 
607
 
 
608
    /**
 
609
     * Creates a default TestResult object.
 
610
     *
 
611
     * @return PHPUnit_Framework_TestResult
 
612
     */
 
613
    protected function createResult()
 
614
    {
 
615
        return new PHPUnit_Framework_TestResult;
 
616
    }
 
617
 
 
618
    /**
 
619
     * Returns the name of the suite.
 
620
     *
 
621
     * @return string
 
622
     */
 
623
    public function getName()
 
624
    {
 
625
        return $this->name;
 
626
    }
 
627
 
 
628
    /**
 
629
     * Returns the test groups of the suite.
 
630
     *
 
631
     * @return array
 
632
     * @since  Method available since Release 3.2.0
 
633
     */
 
634
    public function getGroups()
 
635
    {
 
636
        return array_keys($this->groups);
 
637
    }
 
638
 
 
639
    /**
 
640
     * Runs the tests and collects their result in a TestResult.
 
641
     *
 
642
     * @param  PHPUnit_Framework_TestResult $result
 
643
     * @param  mixed                        $filter
 
644
     * @param  array                        $groups
 
645
     * @param  array                        $excludeGroups
 
646
     * @param  boolean                      $processIsolation
 
647
     * @return PHPUnit_Framework_TestResult
 
648
     * @throws InvalidArgumentException
 
649
     */
 
650
    public function run(PHPUnit_Framework_TestResult $result = NULL, $filter = FALSE, array $groups = array(), array $excludeGroups = array(), $processIsolation = FALSE)
 
651
    {
 
652
        if ($result === NULL) {
 
653
            $result = $this->createResult();
 
654
        }
 
655
 
 
656
        $result->startTestSuite($this);
 
657
 
 
658
        try {
 
659
            $this->setUp();
 
660
 
 
661
            if ($this->testCase &&
 
662
                method_exists($this->name, 'setUpBeforeClass')) {
 
663
                call_user_func(array($this->name, 'setUpBeforeClass'));
 
664
            }
 
665
        }
 
666
 
 
667
        catch (PHPUnit_Framework_SkippedTestSuiteError $e) {
 
668
            $numTests = count($this);
 
669
 
 
670
            for ($i = 0; $i < $numTests; $i++) {
 
671
                $result->addFailure($this, $e, 0);
 
672
            }
 
673
 
 
674
            return $result;
 
675
        }
 
676
 
 
677
        if (empty($groups)) {
 
678
            $tests = $this->tests;
 
679
        } else {
 
680
            $tests = new SplObjectStorage;
 
681
 
 
682
            foreach ($groups as $group) {
 
683
                if (isset($this->groups[$group])) {
 
684
                    foreach ($this->groups[$group] as $test) {
 
685
                        $tests->attach($test);
 
686
                    }
 
687
                }
 
688
            }
 
689
        }
 
690
 
 
691
        foreach ($tests as $test) {
 
692
            if ($result->shouldStop()) {
 
693
                break;
 
694
            }
 
695
 
 
696
            if ($test instanceof PHPUnit_Framework_TestSuite) {
 
697
                $test->setBackupGlobals($this->backupGlobals);
 
698
                $test->setBackupStaticAttributes($this->backupStaticAttributes);
 
699
 
 
700
                $test->run(
 
701
                  $result, $filter, $groups, $excludeGroups, $processIsolation
 
702
                );
 
703
            } else {
 
704
                $runTest = TRUE;
 
705
 
 
706
                if ($filter !== FALSE ) {
 
707
                    $tmp = PHPUnit_Util_Test::describe($test, FALSE);
 
708
 
 
709
                    if ($tmp[0] != '') {
 
710
                        $name = join('::', $tmp);
 
711
                    } else {
 
712
                        $name = $tmp[1];
 
713
                    }
 
714
 
 
715
                    if (preg_match($filter, $name) == 0) {
 
716
                        $runTest = FALSE;
 
717
                    }
 
718
                }
 
719
 
 
720
                if ($runTest && !empty($excludeGroups)) {
 
721
                    foreach ($this->groups as $_group => $_tests) {
 
722
                        if (in_array($_group, $excludeGroups)) {
 
723
                            foreach ($_tests as $_test) {
 
724
                                if ($test === $_test) {
 
725
                                    $runTest = FALSE;
 
726
                                    break 2;
 
727
                                }
 
728
                            }
 
729
                        }
 
730
                    }
 
731
                }
 
732
 
 
733
                if ($runTest) {
 
734
                    if ($test instanceof PHPUnit_Framework_TestCase) {
 
735
                        $test->setBackupGlobals($this->backupGlobals);
 
736
                        $test->setBackupStaticAttributes(
 
737
                          $this->backupStaticAttributes
 
738
                        );
 
739
                        $test->setRunTestInSeparateProcess($processIsolation);
 
740
                    }
 
741
 
 
742
                    $this->runTest($test, $result);
 
743
                }
 
744
            }
 
745
        }
 
746
 
 
747
        if ($this->testCase &&
 
748
            method_exists($this->name, 'tearDownAfterClass')) {
 
749
            call_user_func(array($this->name, 'tearDownAfterClass'));
 
750
        }
 
751
 
 
752
        $this->tearDown();
 
753
        $result->endTestSuite($this);
 
754
 
 
755
        return $result;
 
756
    }
 
757
 
 
758
    /**
 
759
     * Runs a test.
 
760
     *
 
761
     * @param  PHPUnit_Framework_Test        $test
 
762
     * @param  PHPUnit_Framework_TestResult  $testResult
 
763
     */
 
764
    public function runTest(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result)
 
765
    {
 
766
        $test->run($result);
 
767
    }
 
768
 
 
769
    /**
 
770
     * Sets the name of the suite.
 
771
     *
 
772
     * @param  string
 
773
     */
 
774
    public function setName($name)
 
775
    {
 
776
        $this->name = $name;
 
777
    }
 
778
 
 
779
    /**
 
780
     * Returns the test at the given index.
 
781
     *
 
782
     * @param  integer
 
783
     * @return PHPUnit_Framework_Test
 
784
     */
 
785
    public function testAt($index)
 
786
    {
 
787
        if (isset($this->tests[$index])) {
 
788
            return $this->tests[$index];
 
789
        } else {
 
790
            return FALSE;
 
791
        }
 
792
    }
 
793
 
 
794
    /**
 
795
     * Returns the tests as an enumeration.
 
796
     *
 
797
     * @return array
 
798
     */
 
799
    public function tests()
 
800
    {
 
801
        return $this->tests;
 
802
    }
 
803
 
 
804
    /**
 
805
     * Mark the test suite as skipped.
 
806
     *
 
807
     * @param  string  $message
 
808
     * @throws PHPUnit_Framework_SkippedTestSuiteError
 
809
     * @since  Method available since Release 3.0.0
 
810
     */
 
811
    public function markTestSuiteSkipped($message = '')
 
812
    {
 
813
        throw new PHPUnit_Framework_SkippedTestSuiteError($message);
 
814
    }
 
815
 
 
816
    /**
 
817
     * @param ReflectionClass  $class
 
818
     * @param ReflectionMethod $method
 
819
     */
 
820
    protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method)
 
821
    {
 
822
        $name = $method->getName();
 
823
 
 
824
        if ($this->isPublicTestMethod($method)) {
 
825
            $test = self::createTest($class, $name);
 
826
 
 
827
            if ($test instanceof PHPUnit_Framework_TestCase ||
 
828
                $test instanceof PHPUnit_Framework_TestSuite_DataProvider) {
 
829
                $test->setDependencies(
 
830
                  PHPUnit_Util_Test::getDependencies($class->getName(), $name)
 
831
                );
 
832
            }
 
833
 
 
834
            $this->addTest($test, PHPUnit_Util_Test::getGroups(
 
835
              $class->getName(), $name)
 
836
            );
 
837
        }
 
838
 
 
839
        else if ($this->isTestMethod($method)) {
 
840
            $this->addTest(
 
841
              self::warning(
 
842
                sprintf(
 
843
                  'Test method "%s" is not public.',
 
844
 
 
845
                  $name
 
846
                )
 
847
              )
 
848
            );
 
849
        }
 
850
    }
 
851
 
 
852
    /**
 
853
     * @param  ReflectionMethod $method
 
854
     * @return boolean
 
855
     */
 
856
    public static function isPublicTestMethod(ReflectionMethod $method)
 
857
    {
 
858
        return (self::isTestMethod($method) && $method->isPublic());
 
859
    }
 
860
 
 
861
    /**
 
862
     * @param  ReflectionMethod $method
 
863
     * @return boolean
 
864
     */
 
865
    public static function isTestMethod(ReflectionMethod $method)
 
866
    {
 
867
        if (strpos($method->name, 'test') === 0) {
 
868
            return TRUE;
 
869
        }
 
870
 
 
871
        // @scenario on TestCase::testMethod()
 
872
        // @test     on TestCase::testMethod()
 
873
        return strpos($method->getDocComment(), '@test')     !== FALSE ||
 
874
               strpos($method->getDocComment(), '@scenario') !== FALSE;
 
875
    }
 
876
 
 
877
    /**
 
878
     * @param  string  $message
 
879
     * @return PHPUnit_Framework_Warning
 
880
     */
 
881
    protected static function warning($message)
 
882
    {
 
883
        return new PHPUnit_Framework_Warning($message);
 
884
    }
 
885
 
 
886
    /**
 
887
     * @param  boolean $backupGlobals
 
888
     * @since  Method available since Release 3.3.0
 
889
     */
 
890
    public function setBackupGlobals($backupGlobals)
 
891
    {
 
892
        if (is_null($this->backupGlobals) && is_bool($backupGlobals)) {
 
893
            $this->backupGlobals = $backupGlobals;
 
894
        }
 
895
    }
 
896
 
 
897
    /**
 
898
     * @param  boolean $backupStaticAttributes
 
899
     * @since  Method available since Release 3.4.0
 
900
     */
 
901
    public function setBackupStaticAttributes($backupStaticAttributes)
 
902
    {
 
903
        if (is_null($this->backupStaticAttributes) &&
 
904
            is_bool($backupStaticAttributes)) {
 
905
            $this->backupStaticAttributes = $backupStaticAttributes;
 
906
        }
 
907
    }
 
908
 
 
909
    /**
 
910
     * Returns an iterator for this test suite.
 
911
     *
 
912
     * @return RecursiveIteratorIterator
 
913
     * @since  Method available since Release 3.1.0
 
914
     */
 
915
    public function getIterator()
 
916
    {
 
917
        return new RecursiveIteratorIterator(
 
918
          new PHPUnit_Util_TestSuiteIterator($this)
 
919
        );
 
920
    }
 
921
 
 
922
    /**
 
923
     * Template Method that is called before the tests
 
924
     * of this test suite are run.
 
925
     *
 
926
     * @since  Method available since Release 3.1.0
 
927
     */
 
928
    protected function setUp()
 
929
    {
 
930
    }
 
931
 
 
932
    /**
 
933
     * Template Method that is called after the tests
 
934
     * of this test suite have finished running.
 
935
     *
 
936
     * @since  Method available since Release 3.1.0
 
937
     */
 
938
    protected function tearDown()
 
939
    {
 
940
    }
 
941
}