Arbit - project tracking

PHPMD

Browse source code

File: / test/ PHP/ PMD/ AbstractTest.php

Type
text/plain text/plain
Last Author
mapi
Version
209
Line Rev. Author Source
1 38 mapi <?php
2 mapi /**
3 mapi * This file is part of PHP_PMD.
4 mapi *
5 mapi * PHP Version 5
6 42 mapi *
7 174 mapi * Copyright (c) 2009-2010, Manuel Pichler <mapi@phpmd.org>.
8 38 mapi * All rights reserved.
9 mapi *
10 mapi * Redistribution and use in source and binary forms, with or without
11 mapi * modification, are permitted provided that the following conditions
12 mapi * are met:
13 mapi *
14 mapi * * Redistributions of source code must retain the above copyright
15 mapi * notice, this list of conditions and the following disclaimer.
16 mapi *
17 mapi * * Redistributions in binary form must reproduce the above copyright
18 mapi * notice, this list of conditions and the following disclaimer in
19 mapi * the documentation and/or other materials provided with the
20 mapi * distribution.
21 mapi *
22 mapi * * Neither the name of Manuel Pichler nor the names of his
23 mapi * contributors may be used to endorse or promote products derived
24 mapi * from this software without specific prior written permission.
25 mapi *
26 mapi * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 mapi * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 mapi * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
29 mapi * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
30 mapi * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31 mapi * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32 mapi * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33 mapi * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34 mapi * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 mapi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
36 mapi * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 mapi * POSSIBILITY OF SUCH DAMAGE.
38 mapi *
39 mapi * @category PHP
40 mapi * @package PHP_PMD
41 174 mapi * @author Manuel Pichler <mapi@phpmd.org>
42 150 mapi * @copyright 2009-2010 Manuel Pichler. All rights reserved.
43 38 mapi * @license http://www.opensource.org/licenses/bsd-license.php BSD License
44 mapi * @version SVN: $Id$
45 174 mapi * @link http://phpmd.org
46 38 mapi */
47 mapi
48 mapi require_once 'PHPUnit/Framework/TestCase.php';
49 mapi
50 mapi /**
51 mapi * Abstract base class for PHP_PMD test cases.
52 mapi *
53 mapi * @category PHP
54 mapi * @package PHP_PMD
55 174 mapi * @author Manuel Pichler <mapi@phpmd.org>
56 150 mapi * @copyright 2009-2010 Manuel Pichler. All rights reserved.
57 38 mapi * @license http://www.opensource.org/licenses/bsd-license.php BSD License
58 mapi * @version Release: @package_version@
59 174 mapi * @link http://phpmd.org
60 38 mapi */
61 mapi abstract class PHP_PMD_AbstractTest extends PHPUnit_Framework_TestCase
62 mapi {
63 mapi /**
64 mapi * Directory with test files.
65 mapi *
66 mapi * @var string $_filesDirectory
67 mapi */
68 mapi private static $_filesDirectory = null;
69 mapi
70 mapi /**
71 42 mapi * Original directory is used to reset a changed working directory.
72 mapi *
73 mapi * @return void
74 mapi */
75 mapi private static $_originalWorkingDirectory = null;
76 mapi
77 mapi /**
78 mapi * Resets a changed working directory.
79 mapi *
80 mapi * @return void
81 mapi */
82 mapi protected function tearDown()
83 mapi {
84 mapi if (self::$_originalWorkingDirectory !== null) {
85 mapi chdir(self::$_originalWorkingDirectory);
86 mapi }
87 mapi
88 mapi self::$_originalWorkingDirectory = null;
89 mapi
90 mapi parent::tearDown();
91 mapi }
92 mapi
93 mapi /**
94 129 mapi * Returns the first class found in a source file related to the calling
95 mapi * test method.
96 mapi *
97 200 mapi * @return PHP_PMD_Node_Class
98 129 mapi */
99 mapi protected function getClass()
100 mapi {
101 200 mapi include_once 'PHP/PMD/Node/Class.php';
102 129 mapi
103 200 mapi return new PHP_PMD_Node_Class(
104 146 mapi $this->_getNodeForCallingTestCase(
105 mapi $this->_parseTestCaseSource()
106 mapi ->getClasses()
107 mapi )
108 mapi );
109 129 mapi }
110 mapi
111 mapi /**
112 205 mapi * Returns the first interface found in a source file related to the calling
113 mapi * test method.
114 mapi *
115 mapi * @return PHP_PMD_Node_Interface
116 mapi */
117 mapi protected function getInterface()
118 mapi {
119 mapi include_once 'PHP/PMD/Node/Interface.php';
120 mapi
121 mapi return new PHP_PMD_Node_Interface(
122 mapi $this->_getNodeForCallingTestCase(
123 mapi $this->_parseTestCaseSource()
124 mapi ->getInterfaces()
125 mapi )
126 mapi );
127 mapi }
128 mapi
129 mapi /**
130 118 mapi * Returns the first method found in a source file related to the calling
131 116 mapi * test method.
132 mapi *
133 200 mapi * @return PHP_PMD_Node_Method
134 116 mapi */
135 118 mapi protected function getMethod()
136 116 mapi {
137 200 mapi include_once 'PHP/PMD/Node/Method.php';
138 116 mapi
139 200 mapi return new PHP_PMD_Node_Method(
140 146 mapi $this->_getNodeForCallingTestCase(
141 mapi $this->_parseTestCaseSource()
142 mapi ->getTypes()
143 mapi ->current()
144 mapi ->getMethods()
145 mapi )
146 mapi );
147 116 mapi }
148 mapi
149 mapi /**
150 118 mapi * Returns the first function found in a source files related to the calling
151 mapi * test method.
152 mapi *
153 200 mapi * @return PHP_PMD_Node_Function
154 118 mapi */
155 mapi protected function getFunction()
156 mapi {
157 200 mapi include_once 'PHP/PMD/Node/Function.php';
158 118 mapi
159 200 mapi return new PHP_PMD_Node_Function(
160 146 mapi $this->_getNodeForCallingTestCase(
161 mapi $this->_parseTestCaseSource()
162 mapi ->getFunctions()
163 mapi )
164 mapi );
165 118 mapi }
166 mapi
167 mapi /**
168 116 mapi * Parses the source code for the calling test method and returns the first
169 mapi * package node found in the parsed file.
170 mapi *
171 mapi * @return PHP_Depend_Code_Package
172 mapi */
173 mapi private function _parseTestCaseSource()
174 mapi {
175 146 mapi $frame = $this->_getCallingTestCase();
176 mapi
177 186 mapi if (preg_match('(_([^_]+)_[^_]+[a-z]([0-9]+)Test)i', $frame['class'], $match)) {
178 mapi $localPath = $match[1] . '/' . $match[2];
179 mapi } else {
180 mapi $localPath = strtr(substr($frame['class'], 8, -4), '_', '/');
181 mapi }
182 mapi
183 116 mapi $sourceFile = sprintf(
184 mapi '%s/_files/%s/%s.php',
185 mapi dirname(__FILE__),
186 186 mapi $localPath,
187 116 mapi $frame['function']
188 mapi );
189 mapi return $this->_parseSource($sourceFile);
190 mapi }
191 mapi
192 mapi /**
193 146 mapi * Returns the trace frame of the calling test case.
194 mapi *
195 mapi * @return array
196 mapi */
197 mapi private function _getCallingTestCase()
198 mapi {
199 mapi foreach (debug_backtrace() as $frame) {
200 mapi if (strpos($frame['function'], 'test') === 0) {
201 mapi return $frame;
202 mapi }
203 mapi }
204 mapi throw new ErrorException('Cannot locate calling test case.');
205 mapi }
206 mapi
207 mapi /**
208 mapi * Returns the PHP_Depend node for the calling test case.
209 mapi *
210 mapi * @param Iterator $nodes The raw input iterator.
211 mapi *
212 mapi * @return PHP_Depend_Code_AbstractItem
213 mapi */
214 mapi private function _getNodeForCallingTestCase(Iterator $nodes)
215 mapi {
216 mapi $frame = $this->_getCallingTestCase();
217 mapi foreach ($nodes as $node) {
218 mapi if ($node->getName() === $frame['function']) {
219 mapi return $node;
220 mapi }
221 mapi }
222 mapi throw new ErrorException('Cannot locate node for test case.');
223 mapi }
224 mapi
225 mapi /**
226 116 mapi * Parses the source of the given file and returns the first package found
227 mapi * in that file.
228 mapi *
229 mapi * @param string $sourceFile Name of the test source file.
230 mapi *
231 mapi * @return PHP_Depend_Code_Package
232 mapi */
233 mapi private function _parseSource($sourceFile)
234 mapi {
235 209 mapi if (file_exists($sourceFile) === false) {
236 mapi throw new ErrorException('Cannot locate source file: ' . $sourceFile);
237 mapi }
238 mapi
239 116 mapi include_once 'PHP/Depend/Parser.php';
240 mapi include_once 'PHP/Depend/Builder/Default.php';
241 mapi include_once 'PHP/Depend/Tokenizer/Internal.php';
242 mapi
243 mapi $tokenizer = new PHP_Depend_Tokenizer_Internal();
244 mapi $tokenizer->setSourceFile($sourceFile);
245 mapi
246 mapi $builder = new PHP_Depend_Builder_Default();
247 mapi
248 mapi $parser = new PHP_Depend_Parser($tokenizer, $builder);
249 mapi $parser->parse();
250 mapi
251 mapi return $builder->getPackages()->current();
252 mapi }
253 mapi
254 mapi /**
255 47 mapi * Creates a mocked class node instance.
256 mapi *
257 mapi * @param string $metric The metric acronym used by PHP_Depend.
258 mapi * @param mixed $value The expected metric return value.
259 mapi *
260 200 mapi * @return PHP_PMD_Node_Class
261 47 mapi */
262 98 mapi protected function getClassMock($metric = null, $value = null)
263 47 mapi {
264 200 mapi include_once 'PHP/PMD/Node/Class.php';
265 47 mapi
266 200 mapi $class = $this->getMock('PHP_PMD_Node_Class', array(), array(null), '', false);
267 98 mapi if ($metric !== null) {
268 mapi $class->expects($this->atLeastOnce())
269 mapi ->method('getMetric')
270 mapi ->with($this->equalTo($metric))
271 mapi ->will($this->returnValue($value));
272 mapi }
273 47 mapi return $class;
274 mapi }
275 mapi
276 mapi /**
277 42 mapi * Creates a mocked method node instance.
278 mapi *
279 mapi * @param string $metric The metric acronym used by PHP_Depend.
280 mapi * @param mixed $value The expected metric return value.
281 mapi *
282 200 mapi * @return PHP_PMD_Node_Method
283 42 mapi */
284 87 mapi protected function getMethodMock($metric = null, $value = null)
285 42 mapi {
286 200 mapi include_once 'PHP/PMD/Node/Method.php';
287 42 mapi
288 87 mapi return $this->initFunctionOrMethod(
289 200 mapi $this->getMock('PHP_PMD_Node_Method', array(), array(null), '', false),
290 87 mapi $metric,
291 mapi $value
292 mapi );
293 mapi }
294 42 mapi
295 87 mapi /**
296 mapi * Creates a mocked function node instance.
297 mapi *
298 mapi * @param string $metric The metric acronym used by PHP_Depend.
299 mapi * @param mixed $value The expected metric return value.
300 mapi *
301 200 mapi * @return PHP_PMD_Node_Function
302 87 mapi */
303 173 mapi protected function createFunctionMock($metric = null, $value = null)
304 87 mapi {
305 200 mapi include_once 'PHP/PMD/Node/Function.php';
306 87 mapi
307 mapi return $this->initFunctionOrMethod(
308 200 mapi $this->getMock('PHP_PMD_Node_Function', array(), array(null), '', false),
309 87 mapi $metric,
310 mapi $value
311 mapi );
312 42 mapi }
313 mapi
314 mapi /**
315 87 mapi * Initializes the getMetric() method of the given function or methode node.
316 mapi *
317 200 mapi * @param PHP_PMD_Node_Function|PHP_PMD_Node_Method $mock Mock instance.
318 87 mapi * @param string $metric Metric acronym.
319 mapi * @param mixed $value Expected value.
320 mapi *
321 200 mapi * @return PHP_PMD_Node_Function|PHP_PMD_Node_Method
322 87 mapi */
323 mapi protected function initFunctionOrMethod($mock, $metric, $value)
324 mapi {
325 mapi if ($metric === null) {
326 mapi return $mock;
327 mapi }
328 mapi
329 mapi $mock->expects($this->atLeastOnce())
330 mapi ->method('getMetric')
331 mapi ->with($this->equalTo($metric))
332 mapi ->will($this->returnValue($value));
333 mapi
334 mapi return $mock;
335 mapi }
336 mapi
337 mapi /**
338 43 mapi * Creates a mocked report instance.
339 mapi *
340 mapi * @param integer $expectedInvokes Number of expected invokes.
341 mapi *
342 mapi * @return PHP_PMD_Report
343 mapi */
344 mapi protected function getReportMock($expectedInvokes = -1)
345 mapi {
346 52 mapi include_once 'PHP/PMD/Report.php';
347 mapi
348 43 mapi $expects = null;
349 mapi if ($expectedInvokes < 0) {
350 mapi $expects = $this->atLeastOnce();
351 mapi } else if ($expectedInvokes === 0) {
352 mapi $expects = $this->never();
353 mapi } else if ($expectedInvokes === 1) {
354 mapi $expects = $this->once();
355 mapi } else {
356 mapi $expects = $this->exactly($expectedInvokes);
357 mapi }
358 mapi
359 mapi $report = $this->getMock('PHP_PMD_Report');
360 mapi $method = $report->expects($expects)
361 87 mapi ->method('addRuleViolation');
362 43 mapi
363 mapi return $report;
364 mapi }
365 mapi
366 mapi /**
367 200 mapi * Creates a mocked {@link PHP_PMD_AbstractRule} instance.
368 mapi *
369 mapi * @return PHP_PMD_AbstractRule
370 mapi */
371 mapi protected function getRuleMock()
372 mapi {
373 mapi include_once 'PHP/PMD/AbstractRule.php';
374 mapi
375 mapi return $this->getMockForAbstractClass('PHP_PMD_AbstractRule');
376 mapi }
377 mapi
378 mapi /**
379 54 mapi * Creates a mocked rule-set instance.
380 mapi *
381 mapi * @param string $expectedClass Optional class name for apply() expected at
382 mapi * least once.
383 159 mapi * @param mixed $count How often should apply() be called?
384 54 mapi *
385 mapi * @return PHP_PMD_RuleSet
386 mapi */
387 159 mapi protected function getRuleSetMock($expectedClass = null, $count = '*')
388 54 mapi {
389 mapi $ruleSet = $this->getMock('PHP_PMD_RuleSet');
390 mapi if ($expectedClass === null) {
391 mapi $ruleSet->expects($this->never())->method('apply');
392 mapi } else {
393 159 mapi $ruleSet->expects($count === '*' ? $this->atLeastOnce() : $this->exactly($count))
394 54 mapi ->method('apply')
395 mapi ->with($this->isInstanceOf($expectedClass));
396 mapi }
397 mapi return $ruleSet;
398 mapi }
399 mapi
400 mapi /**
401 52 mapi * Creates a mocked rul violation instance.
402 mapi *
403 mapi * @param string $fileName The source code filename.
404 mapi * @param integer $beginLine The first line where the violation context begins.
405 mapi * @param integer $endLine The last line where the violation context ends.
406 55 mapi * @param object $rule A rule instance to return.
407 52 mapi *
408 mapi * @return PHP_PMD_RuleViolation
409 mapi */
410 87 mapi protected function getRuleViolationMock(
411 mapi $fileName = '/foo/bar.php',
412 mapi $beginLine = 23,
413 mapi $endLine = 42,
414 mapi $rule = null
415 mapi ) {
416 52 mapi include_once 'PHP/PMD/RuleViolation.php';
417 mapi
418 87 mapi $ruleViolation = $this->getMock(
419 mapi 'PHP_PMD_RuleViolation',
420 mapi array(),
421 mapi array(null, null, null),
422 mapi '',
423 mapi false
424 mapi );
425 52 mapi
426 55 mapi if ($rule === null) {
427 mapi include_once self::createFileUri('stubs/RuleStub.php');
428 mapi
429 mapi $rule = new PHP_PMD_Stubs_RuleStub();
430 mapi }
431 mapi
432 52 mapi $ruleViolation->expects($this->any())
433 87 mapi ->method('getRule')
434 mapi ->will($this->returnValue($rule));
435 55 mapi $ruleViolation->expects($this->any())
436 87 mapi ->method('getFileName')
437 mapi ->will($this->returnValue($fileName));
438 52 mapi $ruleViolation->expects($this->any())
439 87 mapi ->method('getBeginLine')
440 mapi ->will($this->returnValue($beginLine));
441 52 mapi $ruleViolation->expects($this->any())
442 87 mapi ->method('getEndLine')
443 mapi ->will($this->returnValue($endLine));
444 58 mapi $ruleViolation->expects($this->any())
445 87 mapi ->method('getPackageName')
446 mapi ->will($this->returnValue('TestStubPackage'));
447 138 mapi $ruleViolation->expects($this->any())
448 mapi ->method('getDescription')
449 mapi ->will($this->returnValue('Test description'));
450 52 mapi
451 mapi return $ruleViolation;
452 mapi }
453 mapi
454 mapi /**
455 59 mapi * Asserts the actual xml output matches against the expected file.
456 mapi *
457 mapi * @param string $actualOutput Generated xml output.
458 mapi * @param string $expectedFileName File with expected xml result.
459 mapi *
460 mapi * @return void
461 mapi */
462 mapi public static function assertXmlEquals($actualOutput, $expectedFileName)
463 mapi {
464 mapi $actual = simplexml_load_string($actualOutput);
465 mapi // Remove dynamic timestamp and duration attribute
466 mapi if (isset($actual['timestamp'])) {
467 mapi $actual['timestamp'] = '';
468 mapi }
469 mapi if (isset($actual['duration'])) {
470 mapi $actual['duration'] = '';
471 mapi }
472 mapi
473 mapi $expected = file_get_contents(self::createFileUri($expectedFileName));
474 61 mapi $expected = str_replace('#{rootDirectory}', dirname(__FILE__), $expected);
475 59 mapi
476 mapi self::assertXmlStringEqualsXmlString(
477 mapi str_replace(array(" ", "\n", "\r", "\t"), '', $expected),
478 mapi str_replace(array(" ", "\n", "\r", "\t"), '', $actual->saveXML())
479 mapi );
480 mapi }
481 mapi
482 mapi /**
483 38 mapi * This method initializes the test environment, it configures the files
484 mapi * directory and sets the include_path for svn versions.
485 mapi *
486 mapi * @return void
487 mapi */
488 mapi public static function init()
489 mapi {
490 42 mapi self::$_filesDirectory = dirname(__FILE__) . '/_files';
491 38 mapi
492 42 mapi // file can contain test rule implementations.
493 mapi $include = self::$_filesDirectory;
494 mapi
495 mapi // Check pear installation
496 mapi if (strpos('@package_version@', '@package_version') === 0) {
497 80 mapi $include .= PATH_SEPARATOR .
498 94 mapi realpath(dirname(__FILE__) . '/../../../source') .
499 80 mapi PATH_SEPARATOR .
500 mapi realpath(dirname(__FILE__) . '/../../../lib/pdepend');
501 38 mapi }
502 mapi
503 mapi // Configure include path
504 80 mapi set_include_path($include . PATH_SEPARATOR . get_include_path());
505 42 mapi
506 mapi // Include PHP_PMD main file to get the whitelist directory
507 mapi include_once 'PHP/PMD.php';
508 mapi $ref = new ReflectionClass('PHP_PMD');
509 mapi
510 mapi // Set source whitelist
511 mapi PHPUnit_Util_Filter::addDirectoryToWhitelist(dirname($ref->getFileName()));
512 38 mapi }
513 mapi
514 mapi /**
515 42 mapi * Changes the working directory for a single test.
516 mapi *
517 mapi * @param string $localPath The temporary working directory.
518 mapi *
519 mapi * @return void
520 mapi */
521 mapi protected static function changeWorkingDirectory($localPath = '')
522 mapi {
523 mapi self::$_originalWorkingDirectory = getcwd();
524 mapi
525 mapi chdir(self::createFileUri($localPath));
526 mapi }
527 mapi
528 mapi /**
529 38 mapi * Creates a full filename for a test content in the <em>_files</b> directory.
530 mapi *
531 mapi * @param string $localPath The local path within the <em>_files</b> dir.
532 mapi *
533 mapi * @return string
534 mapi */
535 42 mapi protected static function createFileUri($localPath = '')
536 38 mapi {
537 mapi return self::$_filesDirectory . '/' . $localPath;
538 mapi }
539 mapi }
540 mapi
541 mapi /**
542 mapi * Init the test environment.
543 mapi */
544 mapi PHP_PMD_AbstractTest::init();