~ubuntu-branches/ubuntu/utopic/php-codesniffer/utopic-proposed

« back to all changes in this revision

Viewing changes to PHP_CodeSniffer-1.3.4/tests/Standards/AbstractSniffUnitTest.php

  • Committer: Package Import Robot
  • Author(s): Thomas Goirand
  • Date: 2012-05-31 16:37:24 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20120531163724-u6aiaubu8ks5dh5z
Tags: 1.3.4-0.1
* Non-maintainer upload.
* New upstream release (Closes: #599617, #634825).
* Swtiched debian/copyright to format 1.0 (rewrite was needed anyway, as the
upstream license changed).
* Switched package to pkg-php-tools and debhelper 8 sequencer.
* Now running unit tests at build time (so depends on phpunit (>= 3.6)).
* Section is now PHP.
* Added missing Build-Depends-Indep: php-pear.
* Added missing ${misc:Depends}.
* Added Vcs fields.
* Added homepage field.
* Reviewed short and long description.
* Added dependency on php-timer.
* Standards-Version: is now 3.9.3 (lots of changes, see above...).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * An abstract class that all sniff unit tests must extend.
 
4
 *
 
5
 * PHP version 5
 
6
 *
 
7
 * @category  PHP
 
8
 * @package   PHP_CodeSniffer
 
9
 * @author    Greg Sherwood <gsherwood@squiz.net>
 
10
 * @author    Marc McIntyre <mmcintyre@squiz.net>
 
11
 * @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
 
12
 * @license   http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
 
13
 * @link      http://pear.php.net/package/PHP_CodeSniffer
 
14
 */
 
15
 
 
16
require_once 'PHPUnit/Framework/TestCase.php';
 
17
 
 
18
/**
 
19
 * An abstract class that all sniff unit tests must extend.
 
20
 *
 
21
 * A sniff unit test checks a .inc file for expected violations of a single
 
22
 * coding standard. Expected errors and warnings that are not found, or
 
23
 * warnings and errors that are not expected, are considered test failures.
 
24
 *
 
25
 * @category  PHP
 
26
 * @package   PHP_CodeSniffer
 
27
 * @author    Greg Sherwood <gsherwood@squiz.net>
 
28
 * @author    Marc McIntyre <mmcintyre@squiz.net>
 
29
 * @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600)
 
30
 * @license   http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
 
31
 * @version   Release: 1.3.4
 
32
 * @link      http://pear.php.net/package/PHP_CodeSniffer
 
33
 */
 
34
abstract class AbstractSniffUnitTest extends PHPUnit_Framework_TestCase
 
35
{
 
36
 
 
37
    /**
 
38
     * The PHP_CodeSniffer object used for testing.
 
39
     *
 
40
     * @var PHP_CodeSniffer
 
41
     */
 
42
    protected static $phpcs = null;
 
43
 
 
44
 
 
45
    /**
 
46
     * Sets up this unit test.
 
47
     *
 
48
     * @return void
 
49
     */
 
50
    protected function setUp()
 
51
    {
 
52
        if (self::$phpcs === null) {
 
53
            self::$phpcs = new PHP_CodeSniffer();
 
54
        }
 
55
 
 
56
    }//end setUp()
 
57
 
 
58
 
 
59
    /**
 
60
     * Should this test be skipped for some reason.
 
61
     *
 
62
     * @return void
 
63
     */
 
64
    protected function shouldSkipTest()
 
65
    {
 
66
        return false;
 
67
 
 
68
    }//end shouldSkipTest()
 
69
 
 
70
 
 
71
    /**
 
72
     * Tests the extending classes Sniff class.
 
73
     *
 
74
     * @return void
 
75
     * @throws PHPUnit_Framework_Error
 
76
     */
 
77
    protected final function runTest()
 
78
    {
 
79
        // Skip this test if we can't run in this environment.
 
80
        if ($this->shouldSkipTest() === true) {
 
81
            $this->markTestSkipped();
 
82
        }
 
83
 
 
84
        // The basis for determining file locations.
 
85
        $basename = substr(get_class($this), 0, -8);
 
86
 
 
87
        // The name of the coding standard we are testing.
 
88
        $standardName = substr($basename, 0, strpos($basename, '_'));
 
89
 
 
90
        // The class name of the sniff we are testing.
 
91
        $sniffClass = str_replace('_Tests_', '_Sniffs_', $basename).'Sniff';
 
92
 
 
93
        if (is_file(dirname(__FILE__).'/../../CodeSniffer.php') === true) {
 
94
            // We have not been installed.
 
95
            $standardsDir = realpath(dirname(__FILE__).'/../../CodeSniffer/Standards');
 
96
            $testFileBase = $standardsDir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $basename).'UnitTest.';
 
97
        } else {
 
98
            // The name of the dummy file we are testing.
 
99
            $testFileBase = dirname(__FILE__).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $basename).'UnitTest.';
 
100
        }
 
101
 
 
102
        // Get a list of all test files to check. These will have the same base
 
103
        // name but different extensions. We ignore the .php file as it is the
 
104
        // class.
 
105
        $testFiles = array();
 
106
 
 
107
        $dir = substr($testFileBase, 0, strrpos($testFileBase, DIRECTORY_SEPARATOR));
 
108
        $di  = new DirectoryIterator($dir);
 
109
 
 
110
        foreach ($di as $file) {
 
111
            $path = $file->getPathname();
 
112
            if (substr($path, 0, strlen($testFileBase)) === $testFileBase) {
 
113
                if ($path !== $testFileBase.'php') {
 
114
                    $testFiles[] = $path;
 
115
                }
 
116
            }
 
117
        }
 
118
 
 
119
        // Get them in order. This is particularly important for multi-file sniffs.
 
120
        sort($testFiles);
 
121
 
 
122
        $failureMessages = array();
 
123
        $multiFileSniff  = false;
 
124
        foreach ($testFiles as $testFile) {
 
125
            try {
 
126
                self::$phpcs->process(array(), $standardName, array($sniffClass));
 
127
                self::$phpcs->setIgnorePatterns(array());
 
128
                self::$phpcs->processFile($testFile);
 
129
                self::$phpcs->processMulti();
 
130
            } catch (Exception $e) {
 
131
                $this->fail('An unexpected exception has been caught: '.$e->getMessage());
 
132
            }
 
133
 
 
134
            // After processing a file, check if the sniff was actually
 
135
            // a multi-file sniff (i.e., had no individual file sniffs).
 
136
            // If it is, we can skip checking of the other files and
 
137
            // do a single multi-file check.
 
138
            $sniffs = self::$phpcs->getTokenSniffs();
 
139
            if (empty($sniffs['file']) === true) {
 
140
                $multiFileSniff = true;
 
141
                break;
 
142
            }
 
143
 
 
144
            $files = self::$phpcs->getFiles();
 
145
            if (empty($files) === true) {
 
146
                // File was skipped for some reason.
 
147
                echo "Skipped: $testFile\n";
 
148
                $this->markTestSkipped();
 
149
            }
 
150
 
 
151
            $file = array_pop($files);
 
152
 
 
153
            $failures        = $this->generateFailureMessages($file);
 
154
            $failureMessages = array_merge($failureMessages, $failures);
 
155
        }//end foreach
 
156
 
 
157
        if ($multiFileSniff === true) {
 
158
            try {
 
159
                self::$phpcs->process(array(), $standardName, array($sniffClass));
 
160
                self::$phpcs->setIgnorePatterns(array());
 
161
                foreach ($testFiles as $testFile) {
 
162
                    self::$phpcs->processFile($testFile);
 
163
                }
 
164
 
 
165
                self::$phpcs->processMulti();
 
166
            } catch (Exception $e) {
 
167
                $this->fail('An unexpected exception has been caught: '.$e->getMessage());
 
168
            }
 
169
 
 
170
            $files = self::$phpcs->getFiles();
 
171
            if (empty($files) === true) {
 
172
                // File was skipped for some reason.
 
173
                $this->markTestSkipped();
 
174
            } else {
 
175
                foreach ($files as $file) {
 
176
                    $failures        = $this->generateFailureMessages($file);
 
177
                    $failureMessages = array_merge($failureMessages, $failures);
 
178
                }
 
179
            }
 
180
        }//end if
 
181
 
 
182
        if (empty($failureMessages) === false) {
 
183
            $this->fail(implode(PHP_EOL, $failureMessages));
 
184
        }
 
185
 
 
186
    }//end testSniff()
 
187
 
 
188
 
 
189
    /**
 
190
     * Generate a list of test failures for a given sniffed file.
 
191
     *
 
192
     * @param PHP_CodeSniffer_File $file The file being tested.
 
193
     *
 
194
     * @return array
 
195
     * @throws PHP_CodeSniffer_Exception
 
196
     */
 
197
    public function generateFailureMessages(PHP_CodeSniffer_File $file)
 
198
    {
 
199
        $testFile = $file->getFilename();
 
200
 
 
201
        $foundErrors      = $file->getErrors();
 
202
        $foundWarnings    = $file->getWarnings();
 
203
        $expectedErrors   = $this->getErrorList(basename($testFile));
 
204
        $expectedWarnings = $this->getWarningList(basename($testFile));
 
205
 
 
206
        if (is_array($expectedErrors) === false) {
 
207
            throw new PHP_CodeSniffer_Exception('getErrorList() must return an array');
 
208
        }
 
209
 
 
210
        if (is_array($expectedWarnings) === false) {
 
211
            throw new PHP_CodeSniffer_Exception('getWarningList() must return an array');
 
212
        }
 
213
 
 
214
        /*
 
215
         We merge errors and warnings together to make it easier
 
216
         to iterate over them and produce the errors string. In this way,
 
217
         we can report on errors and warnings in the same line even though
 
218
         it's not really structured to allow that.
 
219
        */
 
220
 
 
221
        $allProblems     = array();
 
222
        $failureMessages = array();
 
223
 
 
224
        foreach ($foundErrors as $line => $lineErrors) {
 
225
            foreach ($lineErrors as $column => $errors) {
 
226
                if (isset($allProblems[$line]) === false) {
 
227
                    $allProblems[$line] = array(
 
228
                                           'expected_errors'   => 0,
 
229
                                           'expected_warnings' => 0,
 
230
                                           'found_errors'      => array(),
 
231
                                           'found_warnings'    => array(),
 
232
                                          );
 
233
                }
 
234
 
 
235
                $foundErrorsTemp = array();
 
236
                foreach ($allProblems[$line]['found_errors'] as $foundError) {
 
237
                    $foundErrorsTemp[] = $foundError;
 
238
                }
 
239
 
 
240
                $errorsTemp = array();
 
241
                foreach ($errors as $foundError) {
 
242
                    $errorsTemp[] = $foundError['message'];
 
243
                }
 
244
 
 
245
                $allProblems[$line]['found_errors'] = array_merge($foundErrorsTemp, $errorsTemp);
 
246
            }
 
247
 
 
248
            if (isset($expectedErrors[$line]) === true) {
 
249
                $allProblems[$line]['expected_errors'] = $expectedErrors[$line];
 
250
            } else {
 
251
                $allProblems[$line]['expected_errors'] = 0;
 
252
            }
 
253
 
 
254
            unset($expectedErrors[$line]);
 
255
        }//end foreach
 
256
 
 
257
        foreach ($expectedErrors as $line => $numErrors) {
 
258
            if (isset($allProblems[$line]) === false) {
 
259
                $allProblems[$line] = array(
 
260
                                       'expected_errors'   => 0,
 
261
                                       'expected_warnings' => 0,
 
262
                                       'found_errors'      => array(),
 
263
                                       'found_warnings'    => array(),
 
264
                                      );
 
265
            }
 
266
 
 
267
            $allProblems[$line]['expected_errors'] = $numErrors;
 
268
        }
 
269
 
 
270
        foreach ($foundWarnings as $line => $lineWarnings) {
 
271
            foreach ($lineWarnings as $column => $warnings) {
 
272
                if (isset($allProblems[$line]) === false) {
 
273
                    $allProblems[$line] = array(
 
274
                                           'expected_errors'   => 0,
 
275
                                           'expected_warnings' => 0,
 
276
                                           'found_errors'      => array(),
 
277
                                           'found_warnings'    => array(),
 
278
                                          );
 
279
                }
 
280
 
 
281
                $foundWarningsTemp = array();
 
282
                foreach ($allProblems[$line]['found_warnings'] as $foundWarning) {
 
283
                    $foundWarningsTemp[] = $foundWarning;
 
284
                }
 
285
 
 
286
                $warningsTemp = array();
 
287
                foreach ($warnings as $warning) {
 
288
                    $warningsTemp[] = $warning['message'];
 
289
                }
 
290
 
 
291
                $allProblems[$line]['found_warnings'] = array_merge($foundWarningsTemp, $warningsTemp);
 
292
            }
 
293
 
 
294
            if (isset($expectedWarnings[$line]) === true) {
 
295
                $allProblems[$line]['expected_warnings'] = $expectedWarnings[$line];
 
296
            } else {
 
297
                $allProblems[$line]['expected_warnings'] = 0;
 
298
            }
 
299
 
 
300
            unset($expectedWarnings[$line]);
 
301
        }//end foreach
 
302
 
 
303
        foreach ($expectedWarnings as $line => $numWarnings) {
 
304
            if (isset($allProblems[$line]) === false) {
 
305
                $allProblems[$line] = array(
 
306
                                       'expected_errors'   => 0,
 
307
                                       'expected_warnings' => 0,
 
308
                                       'found_errors'      => array(),
 
309
                                       'found_warnings'    => array(),
 
310
                                      );
 
311
            }
 
312
 
 
313
            $allProblems[$line]['expected_warnings'] = $numWarnings;
 
314
        }
 
315
 
 
316
        // Order the messages by line number.
 
317
        ksort($allProblems);
 
318
 
 
319
        foreach ($allProblems as $line => $problems) {
 
320
            $numErrors        = count($problems['found_errors']);
 
321
            $numWarnings      = count($problems['found_warnings']);
 
322
            $expectedErrors   = $problems['expected_errors'];
 
323
            $expectedWarnings = $problems['expected_warnings'];
 
324
 
 
325
            $errors      = '';
 
326
            $foundString = '';
 
327
 
 
328
            if ($expectedErrors !== $numErrors || $expectedWarnings !== $numWarnings) {
 
329
                $lineMessage     = "[LINE $line]";
 
330
                $expectedMessage = 'Expected ';
 
331
                $foundMessage    = 'in '.basename($testFile).' but found ';
 
332
 
 
333
                if ($expectedErrors !== $numErrors) {
 
334
                    $expectedMessage .= "$expectedErrors error(s)";
 
335
                    $foundMessage    .= "$numErrors error(s)";
 
336
                    if ($numErrors !== 0) {
 
337
                        $foundString .= 'error(s)';
 
338
                        $errors      .= implode(PHP_EOL.' -> ', $problems['found_errors']);
 
339
                    }
 
340
 
 
341
                    if ($expectedWarnings !== $numWarnings) {
 
342
                        $expectedMessage .= ' and ';
 
343
                        $foundMessage    .= ' and ';
 
344
                        if ($numWarnings !== 0) {
 
345
                            if ($foundString !== '') {
 
346
                                $foundString .= ' and ';
 
347
                            }
 
348
                        }
 
349
                    }
 
350
                }
 
351
 
 
352
                if ($expectedWarnings !== $numWarnings) {
 
353
                    $expectedMessage .= "$expectedWarnings warning(s)";
 
354
                    $foundMessage    .= "$numWarnings warning(s)";
 
355
                    if ($numWarnings !== 0) {
 
356
                        $foundString .= 'warning(s)';
 
357
                        if (empty($errors) === false) {
 
358
                            $errors .= PHP_EOL.' -> ';
 
359
                        }
 
360
 
 
361
                        $errors .= implode(PHP_EOL.' -> ', $problems['found_warnings']);
 
362
                    }
 
363
                }
 
364
 
 
365
                $fullMessage = "$lineMessage $expectedMessage $foundMessage.";
 
366
                if ($errors !== '') {
 
367
                    $fullMessage .= " The $foundString found were:".PHP_EOL." -> $errors";
 
368
                }
 
369
 
 
370
                $failureMessages[] = $fullMessage;
 
371
            }//end if
 
372
        }//end foreach
 
373
 
 
374
        return $failureMessages;
 
375
 
 
376
    }//end generateFailureMessages()
 
377
 
 
378
 
 
379
    /**
 
380
     * Returns the lines where errors should occur.
 
381
     *
 
382
     * The key of the array should represent the line number and the value
 
383
     * should represent the number of errors that should occur on that line.
 
384
     *
 
385
     * @return array(int => int)
 
386
     */
 
387
    protected abstract function getErrorList();
 
388
 
 
389
 
 
390
    /**
 
391
     * Returns the lines where warnings should occur.
 
392
     *
 
393
     * The key of the array should represent the line number and the value
 
394
     * should represent the number of warnings that should occur on that line.
 
395
     *
 
396
     * @return array(int => int)
 
397
     */
 
398
    protected abstract function getWarningList();
 
399
 
 
400
 
 
401
}//end class
 
402
 
 
403
?>