Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
PHPUnitClassUsageSniff
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 2
72
0.00% covered (danger)
0.00%
0 / 1
 register
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 process
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2/**
3 * Copyright (C) 2018 Kunal Mehta <legoktm@member.fsf.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20namespace MediaWiki\Sniffs\PHPUnit;
21
22use PHP_CodeSniffer\Files\File;
23use PHP_CodeSniffer\Sniffs\Sniff;
24use PHP_CodeSniffer\Util\Tokens;
25use PHPUnit\Framework\TestCase;
26
27/**
28 * Converts PHPUnit_Framework_TestCase to the new
29 * PHPUnit 6 namespaced PHPUnit\Framework\Testcase
30 *
31 * The namespaced classes were backported in 4.8.35,
32 * so this is compatible with 4.8.35+ and 5.4.3+
33 */
34class PHPUnitClassUsageSniff implements Sniff {
35    /**
36     * Only look for classes that extend something
37     *
38     * @inheritDoc
39     */
40    public function register(): array {
41        return [ T_EXTENDS ];
42    }
43
44    /**
45     * @param File $phpcsFile
46     * @param int $stackPtr Position of extends token
47     * @return void
48     */
49    public function process( File $phpcsFile, $stackPtr ) {
50        $tokens = $phpcsFile->getTokens();
51        // Skip the "extends" (1) and the class name (1 or more) surrounded by spaces (2).
52        $classPtr = $phpcsFile->findPrevious( Tokens::$ooScopeTokens, $stackPtr - 4 );
53        if ( !$classPtr || $tokens[$classPtr]['code'] !== T_CLASS ) {
54            // interface Foo extends .. which we don't care about
55            return;
56        }
57        $phpunitPtr = $phpcsFile->findNext( T_STRING, $stackPtr );
58        $phpunitToken = $tokens[$phpunitPtr];
59        if ( $phpunitToken['content'] !== 'PHPUnit_Framework_TestCase' ) {
60            return;
61        }
62
63        $fix = $phpcsFile->addFixableWarning(
64            'Namespaced PHPUnit TestCase class should be used instead',
65            $phpunitPtr,
66            'NotNamespaced'
67        );
68        if ( $fix ) {
69            $new = TestCase::class;
70            // If this file is namespaced, we need a leading \
71            $inANamespace = $phpcsFile->findPrevious( T_NAMESPACE, $classPtr ) !== false;
72            $classNameWithSlash = $phpcsFile->findExtendedClassName( $classPtr );
73            // But make sure it doesn't already have a slash...
74            $hashLeadingSlash = $classNameWithSlash[0] === '\\';
75            if ( $inANamespace && !$hashLeadingSlash ) {
76                $new = '\\' . $new;
77            }
78            $phpcsFile->fixer->replaceToken( $phpunitPtr, $new );
79        }
80    }
81}