Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * PHPUnit
4
 *
5
 * Copyright (c) 2002-2010, Sebastian Bergmann <sb@sebastian-bergmann.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
 * @category   Testing
38
 * @package    PHPUnit
39
 * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
40
 * @copyright  2002-2010 Sebastian Bergmann <sb@sebastian-bergmann.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 3.3.0
44
 */
45
 
46
require_once 'PHPUnit/Util/Filesystem.php';
47
require_once 'PHPUnit/Util/Filter.php';
48
require_once 'PHPUnit/Util/Skeleton.php';
49
require_once 'PHPUnit/Util/Template.php';
50
 
51
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
52
 
53
/**
54
 * Generator for test class skeletons from classes.
55
 *
56
 * @category   Testing
57
 * @package    PHPUnit
58
 * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
59
 * @copyright  2002-2010 Sebastian Bergmann <sb@sebastian-bergmann.de>
60
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
61
 * @version    Release: 3.4.15
62
 * @link       http://www.phpunit.de/
63
 * @since      Class available since Release 3.3.0
64
 */
65
class PHPUnit_Util_Skeleton_Test extends PHPUnit_Util_Skeleton
66
{
67
    /**
68
     * @var    array
69
     */
70
    protected $methodNameCounter = array();
71
 
72
    /**
73
     * Constructor.
74
     *
75
     * @param string $inClassName
76
     * @param string $inSourceFile
77
     * @param string $outClassName
78
     * @param string $outSourceFile
79
     * @throws RuntimeException
80
     */
81
    public function __construct($inClassName, $inSourceFile = '', $outClassName = '', $outSourceFile = '')
82
    {
83
        if (class_exists($inClassName)) {
84
            $reflector    = new ReflectionClass($inClassName);
85
            $inSourceFile = $reflector->getFileName();
86
 
87
            if ($inSourceFile === FALSE) {
88
                $inSourceFile = '<internal>';
89
            }
90
 
91
            unset($reflector);
92
        } else {
93
            if (empty($inSourceFile)) {
94
                $possibleFilenames = array(
95
                  $inClassName . '.php',
96
                  PHPUnit_Util_Filesystem::classNameToFilename($inClassName)
97
                );
98
 
99
                foreach ($possibleFilenames as $possibleFilename) {
100
                    if (is_file($possibleFilename)) {
101
                        $inSourceFile = $possibleFilename;
102
                    }
103
                }
104
            }
105
 
106
            if (empty($inSourceFile)) {
107
                throw new PHPUnit_Framework_Exception(
108
                  sprintf(
109
                    'Neither "%s" nor "%s" could be opened.',
110
                    $possibleFilenames[0],
111
                    $possibleFilenames[1]
112
                  )
113
                );
114
            }
115
 
116
            if (!is_file($inSourceFile)) {
117
                throw new PHPUnit_Framework_Exception(
118
                  sprintf(
119
                    '"%s" could not be opened.',
120
 
121
                    $inSourceFile
122
                  )
123
                );
124
            }
125
 
126
            $inSourceFile = realpath($inSourceFile);
127
            include_once $inSourceFile;
128
 
129
            if (!class_exists($inClassName)) {
130
                throw new PHPUnit_Framework_Exception(
131
                  sprintf(
132
                    'Could not find class "%s" in "%s".',
133
 
134
                    $inClassName,
135
                    $inSourceFile
136
                  )
137
                );
138
            }
139
        }
140
 
141
        if (empty($outClassName)) {
142
            $outClassName = $inClassName . 'Test';
143
        }
144
 
145
        if (empty($outSourceFile)) {
146
            $outSourceFile = dirname($inSourceFile) . DIRECTORY_SEPARATOR . $outClassName . '.php';
147
        }
148
 
149
        parent::__construct(
150
          $inClassName, $inSourceFile, $outClassName, $outSourceFile
151
        );
152
    }
153
 
154
    /**
155
     * Generates the test class' source.
156
     *
157
     * @param  boolean $verbose
158
     * @return mixed
159
     */
160
    public function generate($verbose = FALSE)
161
    {
162
        $class             = new ReflectionClass(
163
                               $this->inClassName['fullyQualifiedClassName']
164
                             );
165
        $methods           = '';
166
        $incompleteMethods = '';
167
 
168
        foreach ($class->getMethods() as $method) {
169
            if (!$method->isConstructor() &&
170
                !$method->isAbstract() &&
171
                 $method->isPublic() &&
172
                 $method->getDeclaringClass()->getName() == $this->inClassName['fullyQualifiedClassName']) {
173
                $assertAnnotationFound = FALSE;
174
 
175
                if (preg_match_all('/@assert(.*)$/Um', $method->getDocComment(), $annotations)) {
176
                    foreach ($annotations[1] as $annotation) {
177
                        if (preg_match('/\((.*)\)\s+([^\s]*)\s+(.*)/', $annotation, $matches)) {
178
                            switch ($matches[2]) {
179
                                case '==': {
180
                                    $assertion = 'Equals';
181
                                }
182
                                break;
183
 
184
                                case '!=': {
185
                                    $assertion = 'NotEquals';
186
                                }
187
                                break;
188
 
189
                                case '===': {
190
                                    $assertion = 'Same';
191
                                }
192
                                break;
193
 
194
                                case '!==': {
195
                                    $assertion = 'NotSame';
196
                                }
197
                                break;
198
 
199
                                case '>': {
200
                                    $assertion = 'GreaterThan';
201
                                }
202
                                break;
203
 
204
                                case '>=': {
205
                                    $assertion = 'GreaterThanOrEqual';
206
                                }
207
                                break;
208
 
209
                                case '<': {
210
                                    $assertion = 'LessThan';
211
                                }
212
                                break;
213
 
214
                                case '<=': {
215
                                    $assertion = 'LessThanOrEqual';
216
                                }
217
                                break;
218
 
219
                                case 'throws': {
220
                                    $assertion = 'exception';
221
                                }
222
                                break;
223
 
224
                                default: {
225
                                    throw new PHPUnit_Framework_Exception(
226
                                      sprintf(
227
                                        'Token "%s" could not be parsed in @assert annotation.',
228
                                        $matches[2]
229
                                      )
230
                                    );
231
                                }
232
                            }
233
 
234
                            if ($assertion == 'exception') {
235
                                $template = 'TestMethodException';
236
                            }
237
 
238
                            else if ($assertion == 'Equals' &&
239
                                     strtolower($matches[3]) == 'true') {
240
                                $assertion = 'True';
241
                                $template  = 'TestMethodBool';
242
                            }
243
 
244
                            else if ($assertion == 'NotEquals' &&
245
                                     strtolower($matches[3]) == 'true') {
246
                                $assertion = 'False';
247
                                $template  = 'TestMethodBool';
248
                            }
249
 
250
                            else if ($assertion == 'Equals' &&
251
                                     strtolower($matches[3]) == 'false') {
252
                                $assertion = 'False';
253
                                $template  = 'TestMethodBool';
254
                            }
255
 
256
                            else if ($assertion == 'NotEquals' &&
257
                                     strtolower($matches[3]) == 'false') {
258
                                $assertion = 'True';
259
                                $template  = 'TestMethodBool';
260
                            }
261
 
262
                            else {
263
                                $template = 'TestMethod';
264
                            }
265
 
266
                            if ($method->isStatic()) {
267
                                $template .= 'Static';
268
                            }
269
 
270
                            $methodTemplate = new PHPUnit_Util_Template(
271
                              sprintf(
272
                                '%s%sTemplate%s%s.tpl',
273
 
274
                                dirname(__FILE__),
275
                                DIRECTORY_SEPARATOR,
276
                                DIRECTORY_SEPARATOR,
277
                                $template
278
                              )
279
                            );
280
 
281
                            $origMethodName = $method->getName();
282
                            $methodName     = ucfirst($origMethodName);
283
 
284
                            if (isset($this->methodNameCounter[$methodName])) {
285
                                $this->methodNameCounter[$methodName]++;
286
                            } else {
287
                                $this->methodNameCounter[$methodName] = 1;
288
                            }
289
 
290
                            if ($this->methodNameCounter[$methodName] > 1) {
291
                                $methodName .= $this->methodNameCounter[$methodName];
292
                            }
293
 
294
                            $methodTemplate->setVar(
295
                              array(
296
                                'annotation'     => trim($annotation),
297
                                'arguments'      => $matches[1],
298
                                'assertion'      => isset($assertion) ? $assertion : '',
299
                                'expected'       => $matches[3],
300
                                'origMethodName' => $origMethodName,
301
                                'className'      => $this->inClassName['fullyQualifiedClassName'],
302
                                'methodName'     => $methodName
303
                              )
304
                            );
305
 
306
                            $methods .= $methodTemplate->render();
307
 
308
                            $assertAnnotationFound = TRUE;
309
                        }
310
                    }
311
                }
312
 
313
                if (!$assertAnnotationFound) {
314
                    $methodTemplate = new PHPUnit_Util_Template(
315
                      sprintf(
316
                        '%s%sTemplate%sIncompleteTestMethod.tpl',
317
 
318
                        dirname(__FILE__),
319
                        DIRECTORY_SEPARATOR,
320
                        DIRECTORY_SEPARATOR
321
                      )
322
                    );
323
 
324
                    $methodTemplate->setVar(
325
                      array(
326
                        'methodName' => ucfirst($method->getName())
327
                      )
328
                    );
329
 
330
                    $incompleteMethods .= $methodTemplate->render();
331
                }
332
            }
333
        }
334
 
335
        $classTemplate = new PHPUnit_Util_Template(
336
          sprintf(
337
            '%s%sTemplate%sTestClass.tpl',
338
 
339
            dirname(__FILE__),
340
            DIRECTORY_SEPARATOR,
341
            DIRECTORY_SEPARATOR
342
          )
343
        );
344
 
345
        if ($this->inSourceFile != '<internal>') {
346
            $requireClassFile = sprintf(
347
              "\n\nrequire_once '%s';",
348
 
349
              $this->inSourceFile
350
            );
351
        } else {
352
            $requireClassFile = '';
353
        }
354
 
355
        if ($this->outClassName['namespace'] != '') {
356
            $namespace = "\nnamespace " .
357
                         $this->outClassName['namespace'] . ";\n";
358
        } else {
359
            $namespace = '';
360
        }
361
 
362
        $classTemplate->setVar(
363
          array(
364
            'namespace'          => $namespace,
365
            'namespaceSeparator' => !empty($namespace) ? '\\' : '',
366
            'className'          => $this->inClassName['className'],
367
            'testClassName'      => $this->outClassName['className'],
368
            'requireClassFile'   => $requireClassFile,
369
            'methods'            => $methods . $incompleteMethods,
370
            'date'               => date('Y-m-d'),
371
            'time'               => date('H:i:s')
372
          )
373
        );
374
 
375
        if (!$verbose) {
376
            return $classTemplate->render();
377
        } else {
378
            return array(
379
              'code'       => $classTemplate->render(),
380
              'incomplete' => empty($methods)
381
            );
382
        }
383
    }
384
}
385
?>