Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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