Skip to content

Commit 3196f11

Browse files
authored
Merge pull request #4 from PHPCSStandards/feature/add-debug-ruleset
New feature: Debug ruleset and sniff
2 parents 86cfb93 + f0607d3 commit 3196f11

14 files changed

Lines changed: 471 additions & 4 deletions

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
/.gitignore export-ignore
1010
/.travis.yml export-ignore
1111
/phpcs.xml.dist export-ignore
12+
/phpunit.xml.dist export-ignore
13+
/phpunit-bootstrap.php export-ignore
14+
/Debug/Tests export-ignore
1215

1316
#
1417
# Auto detect text files and perform LF normalization

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ vendor/
22
composer.lock
33
.phpcs.xml
44
phpcs.xml
5+
phpunit.xml

.travis.yml

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,39 @@ cache:
1313

1414
php:
1515
- 5.4
16-
- 7.3
16+
- 5.5
17+
- 5.6
18+
- 7.0
19+
- 7.1
20+
- 7.2
21+
22+
env:
23+
matrix:
24+
# `master`
25+
- PHPCS_VERSION="dev-master" LINT=1
26+
# Lowest supported PHPCS version.
27+
# In reality this is 3.0.2, but there is a bug in the unit test runner of that version.
28+
- PHPCS_VERSION="3.0.2"
1729

1830
# Define the stages used.
31+
# For non-PRs, only the sniff and quicktest stages are run.
32+
# For pull requests and merges, the full script is run (skipping quicktest).
33+
# Note: for pull requests, "develop" is the base branch name.
34+
# See: https://docs.travis-ci.com/user/conditions-v1
1935
stages:
2036
- name: sniff
37+
- name: quicktest
38+
if: type = push AND branch NOT IN (master, develop)
2139
- name: test
40+
if: branch IN (master, develop)
2241

2342
jobs:
2443
fast_finish: true
2544
include:
2645
#### SNIFF STAGE ####
2746
- stage: sniff
2847
php: 7.3
48+
env: PHPCS_VERSION="dev-master"
2949
addons:
3050
apt:
3151
packages:
@@ -36,27 +56,89 @@ jobs:
3656

3757
# Validate the xml file.
3858
# @link http://xmlsoft.org/xmllint.html
59+
- xmllint --noout --schema ./vendor/squizlabs/php_codesniffer/phpcs.xsd ./Debug/ruleset.xml
3960
- xmllint --noout --schema ./vendor/squizlabs/php_codesniffer/phpcs.xsd ./PHPCSDev/ruleset.xml
4061

4162
# Check the code-style consistency of the xml files.
63+
- diff -B ./Debug/ruleset.xml <(xmllint --format "./Debug/ruleset.xml")
4264
- diff -B ./PHPCSDev/ruleset.xml <(xmllint --format "./PHPCSDev/ruleset.xml")
4365

4466

67+
#### QUICK TEST STAGE ####
68+
# This is a much quicker test which only runs the unit tests and linting against the low/high
69+
# supported PHP/PHPCS combinations.
70+
- stage: quicktest
71+
php: 7.3
72+
env: PHPCS_VERSION="dev-master" LINT=1
73+
- php: 7.2
74+
env: PHPCS_VERSION="3.0.2"
75+
76+
- php: 5.4
77+
env: PHPCS_VERSION="dev-master" LINT=1
78+
- php: 5.4
79+
env: PHPCS_VERSION="3.0.2"
80+
81+
#### TEST STAGE ####
82+
# Additional builds to prevent issues with PHPCS versions incompatible with certain PHP versions.
83+
- stage: test
84+
php: 7.3
85+
env: PHPCS_VERSION="dev-master" LINT=1
86+
# PHPCS is only compatible with PHP 7.3 as of version 3.3.1.
87+
- php: 7.3
88+
env: PHPCS_VERSION="3.3.1"
89+
# PHPCS is only compatible with PHP 7.4 as of version 3.5.0.
90+
- php: "7.4snapshot"
91+
env: PHPCS_VERSION=dev-master"
92+
93+
allow_failures:
94+
# Allow failures for unstable builds.
95+
- php: "7.4snapshot"
96+
97+
4598
before_install:
4699
# Speed up build time by disabling Xdebug when its not needed.
47100
- phpenv config-rm xdebug.ini || echo 'No xdebug config.'
48101

102+
# On stable PHPCS versions, allow for PHP deprecation notices.
103+
# Unit tests don't need to fail on those for stable releases where those issues won't get fixed anymore.
104+
- |
105+
if [[ "$TRAVIS_BUILD_STAGE_NAME" != "Sniff" && $PHPCS_BRANCH != "dev-master" ]]; then
106+
echo 'error_reporting = E_ALL & ~E_DEPRECATED' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
107+
fi
108+
49109
- export XMLLINT_INDENT=" "
50110

111+
# Set up test environment using Composer.
112+
- composer require --no-update --no-scripts squizlabs/php_codesniffer:${PHPCS_VERSION}
113+
- |
114+
if [[ "$TRAVIS_BUILD_STAGE_NAME" == "Sniff" ]]; then
115+
# The sniff stage doesn't run the unit tests, so no need for PHPUnit.
116+
composer remove --dev phpunit/phpunit --no-update --no-scripts
117+
elif [[ "$PHPCS_VERSION" < "3.1.0" ]]; then
118+
# PHPCS < 3.1.0 is not compatible with PHPUnit 6.x.
119+
composer require --dev phpunit/phpunit:"^4.0||^5.0" --no-update --no-scripts
120+
elif [[ "$PHPCS_VERSION" < "3.2.3" ]]; then
121+
# PHPCS < 3.2.3 is not compatible with PHPUnit 7.x.
122+
composer require --dev phpunit/phpunit:"^4.0||^5.0||^6.0" --no-update --no-scripts
123+
fi
124+
51125
# --prefer-dist will allow for optimal use of the travis caching ability.
52126
# The Composer PHPCS plugin takes care of setting the installed_paths for PHPCS.
53127
- composer install --prefer-dist --no-suggest
54128

55129

56130
script:
57131
# Lint PHP files against parse errors.
58-
- composer lint
132+
- if [[ "$LINT" == "1" ]]; then composer lint; fi
133+
134+
# Check that any sniffs available are feature complete.
135+
# This also acts as an integration test for the feature completeness script,
136+
# which is why it is run against various PHP versions and not in the "Sniff" stage.
137+
- if [[ "$LINT" == "1" ]]; then composer check-complete; fi
59138

60-
# Validate the composer.json file on low/high PHP versions.
139+
# Validate the composer.json file.
61140
# @link https://getcomposer.org/doc/03-cli.md#validate
62-
- composer validate --no-check-all --strict
141+
- if [[ "$LINT" == "1" ]]; then composer validate --no-check-all --strict; fi
142+
143+
# Run the unit tests.
144+
- composer run-tests
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<documentation title="Token List">
2+
<standard>
3+
<![CDATA[
4+
Lists how PHPCS tokenizes code.
5+
6+
This sniff will not throw any warnings or errors, but is solely intended as a tool for sniff developers.
7+
]]>
8+
</standard>
9+
</documentation>
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
/**
3+
* PHPCSDevTools, tools for PHP_CodeSniffer sniff developers.
4+
*
5+
* @package PHPCSDevTools
6+
* @copyright 2019 PHPCSDevTools Contributors
7+
* @license https://opensource.org/licenses/LGPL-3.0 LGPL3
8+
* @link https://github.com/PHPCSStandards/PHPCSDevTools
9+
*/
10+
11+
namespace PHPCSStandards\Debug\Sniffs\Debug;
12+
13+
use PHP_CodeSniffer\Sniffs\Sniff;
14+
use PHP_CodeSniffer\Files\File;
15+
16+
/**
17+
* Lists how PHPCS tokenizes code.
18+
*
19+
* This sniff will not throw any warnings or errors, but is solely intended
20+
* as a tool for sniff developers.
21+
*
22+
* @since 1.0.0
23+
*/
24+
class TokenListSniff implements Sniff
25+
{
26+
27+
/**
28+
* A list of tokenizers this sniff supports.
29+
*
30+
* @var array
31+
*/
32+
public $supportedTokenizers = [
33+
'PHP',
34+
'JS',
35+
'CSS',
36+
];
37+
38+
/**
39+
* Returns an array of tokens this test wants to listen for.
40+
*
41+
* @return array
42+
*/
43+
public function register()
44+
{
45+
return [
46+
\T_OPEN_TAG,
47+
\T_OPEN_TAG_WITH_ECHO,
48+
];
49+
}
50+
51+
/**
52+
* Processes this test, when one of its tokens is encountered.
53+
*
54+
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
55+
* @param int $stackPtr The position of the current
56+
* token in the stack.
57+
*
58+
* @return void
59+
*/
60+
public function process(File $phpcsFile, $stackPtr)
61+
{
62+
$tokens = $phpcsFile->getTokens();
63+
64+
$oldIniValue = \ini_set('xdebug.overload_var_dump', 1);
65+
66+
echo \PHP_EOL;
67+
foreach ($tokens as $ptr => $token) {
68+
if (isset($token['length']) === false) {
69+
$token['length'] = strlen($token['content']);
70+
}
71+
72+
$content = $token['content'];
73+
if ($token['code'] === \T_WHITESPACE
74+
|| (defined('T_DOC_COMMENT_WHITESPACE')
75+
&& $token['code'] === \T_DOC_COMMENT_WHITESPACE)
76+
) {
77+
if (strpos($token['content'], "\t") !== false) {
78+
$content = str_replace("\t", '\t', $token['content']);
79+
}
80+
if (isset($token['orig_content'])) {
81+
$content .= ' :: Orig: ' . str_replace("\t", '\t', $token['orig_content']);
82+
}
83+
}
84+
85+
echo $ptr, ' :: L', \str_pad($token['line'], 3, '0', \STR_PAD_LEFT), ' :: C', $token['column'],
86+
' :: ', $token['type'], ' :: (', $token['length'], ') :: ', $content, \PHP_EOL;
87+
}
88+
89+
// If necessary, reset the ini setting.
90+
if ($oldIniValue !== false) {
91+
\ini_set('xdebug.overload_var_dump', $oldIniValue);
92+
}
93+
94+
// Only do this once per file.
95+
return ($phpcsFile->numTokens + 1);
96+
}
97+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?php
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
/**
3+
* PHPCSDevTools, tools for PHP_CodeSniffer sniff developers.
4+
*
5+
* @package PHPCSDevTools
6+
* @copyright 2019 PHPCSDevTools Contributors
7+
* @license https://opensource.org/licenses/LGPL-3.0 LGPL3
8+
* @link https://github.com/PHPCSStandards/PHPCSDevTools
9+
*/
10+
11+
namespace PHPCSStandards\Debug\Tests\Debug;
12+
13+
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
14+
15+
/**
16+
* Unit test class for the TokenList sniff.
17+
*
18+
* @covers PHPCSStandards\Debug\Sniffs\Debug::TokenListSniff
19+
*
20+
* @since 1.0.0
21+
*/
22+
class TokenListUnitTest extends AbstractSniffUnitTest
23+
{
24+
25+
/**
26+
* Cache any output generated during the test.
27+
*
28+
* @var string
29+
*/
30+
public static $output = '';
31+
32+
/**
33+
* Sets up this unit test.
34+
*
35+
* @return void
36+
*/
37+
protected function setUp()
38+
{
39+
parent::setUp();
40+
41+
ob_start();
42+
}
43+
44+
/**
45+
* Clean up.
46+
*
47+
* @return void
48+
*/
49+
protected function tearDown()
50+
{
51+
self::$output = ob_get_flush();
52+
53+
parent::tearDown();
54+
}
55+
56+
/**
57+
* Returns the lines where errors should occur.
58+
*
59+
* @return array <int line number> => <int number of errors>
60+
*/
61+
public function getErrorList()
62+
{
63+
return [];
64+
}
65+
66+
/**
67+
* Returns the lines where warnings should occur.
68+
*
69+
* @return array <int line number> => <int number of warnings>
70+
*/
71+
public function getWarningList()
72+
{
73+
return [];
74+
}
75+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
/**
3+
* PHPCSDevTools, tools for PHP_CodeSniffer sniff developers.
4+
*
5+
* @package PHPCSDevTools
6+
* @copyright 2019 PHPCSDevTools Contributors
7+
* @license https://opensource.org/licenses/LGPL-3.0 LGPL3
8+
* @link https://github.com/PHPCSStandards/PHPCSDevTools
9+
*/
10+
11+
namespace PHPCSStandards\Debug\Tests\Debug;
12+
13+
use PHPUnit\Framework\TestCase;
14+
15+
/**
16+
* Unit test class for the TokenList sniff.
17+
*
18+
* @covers PHPCSStandards\Debug\Sniffs\Debug::TokenListSniff
19+
*
20+
* @since 1.0.0
21+
*/
22+
class TokenListZUnitTest extends TestCase
23+
{
24+
25+
/**
26+
* Test the actual output of the TokenList sniff.
27+
*
28+
* @return void
29+
*/
30+
public function testOutput()
31+
{
32+
$output = trim(TokenListUnitTest::$output);
33+
34+
$this->assertNotEmpty($output);
35+
36+
$expected = '0 :: L001 :: C1 :: T_OPEN_TAG :: (5) :: <?php';
37+
$this->assertSame($expected, $output);
38+
}
39+
}

Debug/ruleset.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0"?>
2+
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Debug" namespace="PHPCSStandards\Debug" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/squizlabs/PHP_CodeSniffer/master/phpcs.xsd">
3+
4+
<description>Sniffs which can be used as debugging tools for PHPCS developers</description>
5+
6+
</ruleset>

0 commit comments

Comments
 (0)