Subversion Repositories Applications.gtt

Rev

Rev 94 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
94 jpm 1
<?php
2
/**
3
 * PEAR_Command_Test (run-tests)
4
 *
5
 * PHP versions 4 and 5
6
 *
7
 * @category   pear
8
 * @package    PEAR
9
 * @author     Stig Bakken <ssb@php.net>
10
 * @author     Martin Jansen <mj@php.net>
11
 * @author     Greg Beaver <cellog@php.net>
187 mathias 12
 * @copyright  1997-2009 The Authors
13
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
94 jpm 14
 * @link       http://pear.php.net/package/PEAR
15
 * @since      File available since Release 0.1
16
 */
17
 
18
/**
19
 * base class
20
 */
21
require_once 'PEAR/Command/Common.php';
22
 
23
/**
24
 * PEAR commands for login/logout
25
 *
26
 * @category   pear
27
 * @package    PEAR
28
 * @author     Stig Bakken <ssb@php.net>
29
 * @author     Martin Jansen <mj@php.net>
30
 * @author     Greg Beaver <cellog@php.net>
187 mathias 31
 * @copyright  1997-2009 The Authors
32
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
33
 * @version    Release: 1.10.1
94 jpm 34
 * @link       http://pear.php.net/package/PEAR
35
 * @since      Class available since Release 0.1
36
 */
37
 
38
class PEAR_Command_Test extends PEAR_Command_Common
39
{
40
    var $commands = array(
41
        'run-tests' => array(
42
            'summary' => 'Run Regression Tests',
43
            'function' => 'doRunTests',
44
            'shortcut' => 'rt',
45
            'options' => array(
46
                'recur' => array(
47
                    'shortopt' => 'r',
48
                    'doc' => 'Run tests in child directories, recursively.  4 dirs deep maximum',
49
                ),
50
                'ini' => array(
51
                    'shortopt' => 'i',
52
                    'doc' => 'actual string of settings to pass to php in format " -d setting=blah"',
53
                    'arg' => 'SETTINGS'
54
                ),
55
                'realtimelog' => array(
56
                    'shortopt' => 'l',
57
                    'doc' => 'Log test runs/results as they are run',
58
                ),
59
                'quiet' => array(
60
                    'shortopt' => 'q',
61
                    'doc' => 'Only display detail for failed tests',
62
                ),
63
                'simple' => array(
64
                    'shortopt' => 's',
65
                    'doc' => 'Display simple output for all tests',
66
                ),
67
                'package' => array(
68
                    'shortopt' => 'p',
69
                    'doc' => 'Treat parameters as installed packages from which to run tests',
70
                ),
71
                'phpunit' => array(
72
                    'shortopt' => 'u',
187 mathias 73
                    'doc' => 'Search parameters for AllTests.php, and use that to run phpunit-based tests
74
If none is found, all .phpt tests will be tried instead.',
94 jpm 75
                ),
76
                'tapoutput' => array(
77
                    'shortopt' => 't',
78
                    'doc' => 'Output run-tests.log in TAP-compliant format',
79
                ),
80
                'cgi' => array(
81
                    'shortopt' => 'c',
82
                    'doc' => 'CGI php executable (needed for tests with POST/GET section)',
83
                    'arg' => 'PHPCGI',
84
                ),
187 mathias 85
                'coverage' => array(
86
                    'shortopt' => 'x',
87
                    'doc'      => 'Generate a code coverage report (requires Xdebug 2.0.0+)',
88
                ),
89
                'showdiff' => array(
90
                    'shortopt' => 'd',
91
                    'doc' => 'Output diff on test failure',
92
                ),
94 jpm 93
            ),
94
            'doc' => '[testfile|dir ...]
95
Run regression tests with PHP\'s regression testing script (run-tests.php).',
96
            ),
97
        );
98
 
99
    var $output;
100
 
101
    /**
102
     * PEAR_Command_Test constructor.
103
     *
104
     * @access public
105
     */
187 mathias 106
    function __construct(&$ui, &$config)
94 jpm 107
    {
187 mathias 108
        parent::__construct($ui, $config);
94 jpm 109
    }
110
 
111
    function doRunTests($command, $options, $params)
112
    {
113
        if (isset($options['phpunit']) && isset($options['tapoutput'])) {
114
            return $this->raiseError('ERROR: cannot use both --phpunit and --tapoutput at the same time');
115
        }
187 mathias 116
 
94 jpm 117
        require_once 'PEAR/Common.php';
118
        require_once 'System.php';
119
        $log = new PEAR_Common;
120
        $log->ui = &$this->ui; // slightly hacky, but it will work
121
        $tests = array();
187 mathias 122
        $depth = isset($options['recur']) ? 14 : 1;
123
 
94 jpm 124
        if (!count($params)) {
125
            $params[] = '.';
126
        }
187 mathias 127
 
94 jpm 128
        if (isset($options['package'])) {
129
            $oldparams = $params;
130
            $params = array();
131
            $reg = &$this->config->getRegistry();
132
            foreach ($oldparams as $param) {
133
                $pname = $reg->parsePackageName($param, $this->config->get('default_channel'));
134
                if (PEAR::isError($pname)) {
135
                    return $this->raiseError($pname);
136
                }
187 mathias 137
 
94 jpm 138
                $package = &$reg->getPackage($pname['package'], $pname['channel']);
139
                if (!$package) {
140
                    return PEAR::raiseError('Unknown package "' .
141
                        $reg->parsedPackageNameToString($pname) . '"');
142
                }
187 mathias 143
 
94 jpm 144
                $filelist = $package->getFilelist();
145
                foreach ($filelist as $name => $atts) {
146
                    if (isset($atts['role']) && $atts['role'] != 'test') {
147
                        continue;
148
                    }
187 mathias 149
 
150
                    if (isset($options['phpunit']) && preg_match('/AllTests\.php\\z/i', $name)) {
151
                        $params[] = $atts['installed_as'];
152
                        continue;
153
                    } elseif (!preg_match('/\.phpt\\z/', $name)) {
154
                        continue;
94 jpm 155
                    }
156
                    $params[] = $atts['installed_as'];
157
                }
158
            }
159
        }
187 mathias 160
 
94 jpm 161
        foreach ($params as $p) {
162
            if (is_dir($p)) {
163
                if (isset($options['phpunit'])) {
164
                    $dir = System::find(array($p, '-type', 'f',
165
                                                '-maxdepth', $depth,
166
                                                '-name', 'AllTests.php'));
187 mathias 167
                    if (count($dir)) {
168
                        foreach ($dir as $p) {
169
                            $p = realpath($p);
170
                            if (!count($tests) ||
171
                                  (count($tests) && strlen($p) < strlen($tests[0]))) {
172
                                // this is in a higher-level directory, use this one instead.
173
                                $tests = array($p);
174
                            }
175
                        }
176
                    }
177
                    continue;
94 jpm 178
                }
187 mathias 179
 
180
                $args  = array($p, '-type', 'f', '-name', '*.phpt');
94 jpm 181
            } else {
182
                if (isset($options['phpunit'])) {
187 mathias 183
                    if (preg_match('/AllTests\.php\\z/i', $p)) {
184
                        $p = realpath($p);
185
                        if (!count($tests) ||
186
                              (count($tests) && strlen($p) < strlen($tests[0]))) {
187
                            // this is in a higher-level directory, use this one instead.
188
                            $tests = array($p);
94 jpm 189
                        }
190
                    }
187 mathias 191
                    continue;
94 jpm 192
                }
187 mathias 193
 
194
                if (file_exists($p) && preg_match('/\.phpt$/', $p)) {
195
                    $tests[] = $p;
196
                    continue;
197
                }
198
 
199
                if (!preg_match('/\.phpt\\z/', $p)) {
200
                    $p .= '.phpt';
201
                }
202
 
203
                $args  = array(dirname($p), '-type', 'f', '-name', $p);
94 jpm 204
            }
187 mathias 205
 
206
            if (!isset($options['recur'])) {
207
                $args[] = '-maxdepth';
208
                $args[] = 1;
209
            }
210
 
211
            $dir   = System::find($args);
212
            $tests = array_merge($tests, $dir);
94 jpm 213
        }
187 mathias 214
 
94 jpm 215
        $ini_settings = '';
216
        if (isset($options['ini'])) {
217
            $ini_settings .= $options['ini'];
218
        }
187 mathias 219
 
94 jpm 220
        if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) {
221
            $ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}";
222
        }
187 mathias 223
 
94 jpm 224
        if ($ini_settings) {
225
            $this->ui->outputData('Using INI settings: "' . $ini_settings . '"');
226
        }
187 mathias 227
 
94 jpm 228
        $skipped = $passed = $failed = array();
187 mathias 229
        $tests_count = count($tests);
230
        $this->ui->outputData('Running ' . $tests_count . ' tests', $command);
94 jpm 231
        $start = time();
187 mathias 232
        if (isset($options['realtimelog']) && file_exists('run-tests.log')) {
233
            unlink('run-tests.log');
94 jpm 234
        }
187 mathias 235
 
94 jpm 236
        if (isset($options['tapoutput'])) {
187 mathias 237
            $tap = '1..' . $tests_count . "\n";
94 jpm 238
        }
187 mathias 239
 
240
        require_once 'PEAR/RunTest.php';
241
        $run = new PEAR_RunTest($log, $options);
242
        $run->tests_count = $tests_count;
243
 
244
        if (isset($options['coverage']) && extension_loaded('xdebug')){
245
            $run->xdebug_loaded = true;
246
        } else {
247
            $run->xdebug_loaded = false;
248
        }
249
 
250
        $j = $i = 1;
94 jpm 251
        foreach ($tests as $t) {
252
            if (isset($options['realtimelog'])) {
253
                $fp = @fopen('run-tests.log', 'a');
254
                if ($fp) {
187 mathias 255
                    fwrite($fp, "Running test [$i / $tests_count] $t...");
94 jpm 256
                    fclose($fp);
257
                }
258
            }
259
            PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
187 mathias 260
            if (isset($options['phpunit'])) {
261
                $result = $run->runPHPUnit($t, $ini_settings);
262
            } else {
263
                $result = $run->run($t, $ini_settings, $j);
264
            }
94 jpm 265
            PEAR::staticPopErrorHandling();
266
            if (PEAR::isError($result)) {
267
                $this->ui->log($result->getMessage());
268
                continue;
269
            }
187 mathias 270
 
94 jpm 271
            if (isset($options['tapoutput'])) {
272
                $tap .= $result[0] . ' ' . $i . $result[1] . "\n";
273
                continue;
274
            }
187 mathias 275
 
94 jpm 276
            if (isset($options['realtimelog'])) {
277
                $fp = @fopen('run-tests.log', 'a');
278
                if ($fp) {
279
                    fwrite($fp, "$result\n");
280
                    fclose($fp);
281
                }
282
            }
187 mathias 283
 
94 jpm 284
            if ($result == 'FAILED') {
187 mathias 285
                $failed[] = $t;
94 jpm 286
            }
287
            if ($result == 'PASSED') {
187 mathias 288
                $passed[] = $t;
94 jpm 289
            }
290
            if ($result == 'SKIPPED') {
187 mathias 291
                $skipped[] = $t;
94 jpm 292
            }
187 mathias 293
 
294
            $j++;
94 jpm 295
        }
187 mathias 296
 
94 jpm 297
        $total = date('i:s', time() - $start);
298
        if (isset($options['tapoutput'])) {
299
            $fp = @fopen('run-tests.log', 'w');
300
            if ($fp) {
301
                fwrite($fp, $tap, strlen($tap));
302
                fclose($fp);
303
                $this->ui->outputData('wrote TAP-format log to "' .realpath('run-tests.log') .
304
                    '"', $command);
305
            }
306
        } else {
307
            if (count($failed)) {
308
                $output = "TOTAL TIME: $total\n";
309
                $output .= count($passed) . " PASSED TESTS\n";
310
                $output .= count($skipped) . " SKIPPED TESTS\n";
187 mathias 311
                $output .= count($failed) . " FAILED TESTS:\n";
312
                foreach ($failed as $failure) {
313
                    $output .= $failure . "\n";
94 jpm 314
                }
187 mathias 315
 
316
                $mode = isset($options['realtimelog']) ? 'a' : 'w';
317
                $fp   = @fopen('run-tests.log', $mode);
318
 
94 jpm 319
                if ($fp) {
320
                    fwrite($fp, $output, strlen($output));
321
                    fclose($fp);
322
                    $this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command);
323
                }
324
            } elseif (file_exists('run-tests.log') && !is_dir('run-tests.log')) {
325
                @unlink('run-tests.log');
326
            }
327
        }
328
        $this->ui->outputData('TOTAL TIME: ' . $total);
329
        $this->ui->outputData(count($passed) . ' PASSED TESTS', $command);
330
        $this->ui->outputData(count($skipped) . ' SKIPPED TESTS', $command);
331
        if (count($failed)) {
187 mathias 332
            $this->ui->outputData(count($failed) . ' FAILED TESTS:', $command);
333
            foreach ($failed as $failure) {
334
                $this->ui->outputData($failure, $command);
335
            }
94 jpm 336
        }
337
 
187 mathias 338
        if (count($failed) == 0) {
339
            return true;
340
        }
341
        return $this->raiseError('Some tests failed');
94 jpm 342
    }
343
}