Skip to content

Commit ab932a7

Browse files
committed
Add tests
1 parent 62d8cf2 commit ab932a7

22 files changed

+2774
-6
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
composer.phar
22
composer.lock
33
/vendor/
4+
/phpunit.xml
45

56
# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
67
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file

Inpsyde/PHPCSAliases.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
<?php
22
/**
3-
* PHPCS cross-version compatibility helper.
4-
*
5-
* @package WPCS\WordPressCodingStandards
6-
* @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards
7-
* @license https://opensource.org/licenses/MIT MIT
8-
* @since 0.13.0
3+
* This file contains code from "WordPress-Coding-Standards" project
4+
* found at https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards
5+
* Copyright (c) 2009 John Godley and contributors.
6+
* released under MIT license.
97
*/
108

9+
if (defined('PHP_CODESNIFFER_IN_TESTS')) {
10+
return;
11+
}
12+
1113
/*
1214
* Alias a number of PHPCS 3.x classes to their PHPCS 2.x equivalents.
1315
*

composer.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@
3434
"sirbrillig/phpcs-variable-analysis": "^2",
3535
"wimg/php-compatibility": "^8.0"
3636
},
37+
"require-dev": {
38+
"phpunit/phpunit": "6.0.*"
39+
},
40+
"autoload-dev": {
41+
"psr-4": {
42+
"Inpsyde\\InpsydeCodingStandard\\Tests\\": "tests/src/"
43+
}
44+
},
3745
"extra": {
3846
"branch-alias": {
3947
"dev-master": "0.4.x-dev"

phpunit.xml.dist

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.0/phpunit.xsd"
5+
backupGlobals="false"
6+
backupStaticAttributes="false"
7+
bootstrap="tests/bootstrap.php"
8+
colors="true"
9+
convertErrorsToExceptions="true"
10+
convertNoticesToExceptions="true"
11+
convertWarningsToExceptions="true"
12+
processIsolation="false"
13+
stopOnFailure="false">
14+
<testsuites>
15+
<testsuite name="fixtures">
16+
<file>tests/cases/FixturesTest.php</file>
17+
</testsuite>
18+
</testsuites>
19+
<filter>
20+
<whitelist processUncoveredFilesFromWhitelist="true">
21+
<directory suffix=".php">src/Sniffs</directory>
22+
<exclude>
23+
<directory>docs</directory>
24+
<directory>tests</directory>
25+
<directory>vendor</directory>
26+
</exclude>
27+
</whitelist>
28+
</filter>
29+
<logging>
30+
<log type="coverage-clover" target="coverage.xml" />
31+
</logging>
32+
</phpunit>

tests/bootstrap.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php # -*- coding: utf-8 -*-
2+
/*
3+
* This file is part of the Wonolog package.
4+
*
5+
* (c) Inpsyde GmbH
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
putenv('SNIFFS_PATH=' . realpath(dirname(__DIR__) . '/Inpsyde/Sniffs'));
12+
putenv('SNIFFS_NAMESPACE=' . 'Inpsyde\\InpsydeCodingStandard\\Sniffs');
13+
putenv('FIXTURES_PATH=' . realpath(__DIR__ . '/fixtures'));
14+
15+
$vendor = dirname(__DIR__) . '/vendor/';
16+
if (!realpath($vendor)) {
17+
die('Please install via Composer before running tests.');
18+
}
19+
20+
require_once($vendor . 'autoload.php');
21+
require_once($vendor . 'squizlabs/php_codesniffer/tests/bootstrap.php');
22+
require_once(dirname(__DIR__) . '/Inpsyde/Helpers.php');
23+
unset($vendor);

tests/cases/FixturesTest.php

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
<?php declare(strict_types=1); # -*- coding: utf-8 -*-
2+
/*
3+
* This file is part of the php-coding-standards package.
4+
*
5+
* (c) Inpsyde GmbH
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
namespace Inpsyde\InpsydeCodingStandard\Tests\Cases;
12+
13+
use Inpsyde\InpsydeCodingStandard\Tests\FixtureContentParser;
14+
use Inpsyde\InpsydeCodingStandard\Tests\SniffMessages;
15+
use Inpsyde\InpsydeCodingStandard\Tests\SniffMessagesExtractor;
16+
use PHP_CodeSniffer\Files\LocalFile;
17+
use PHP_CodeSniffer\Files\File;
18+
use PHP_CodeSniffer\Ruleset;
19+
use PHP_CodeSniffer\Config;
20+
use PHPUnit\Framework\AssertionFailedError;
21+
use PHPUnit\Framework\Exception;
22+
use PHPUnit\Framework\TestCase;
23+
24+
/**
25+
* @package php-coding-standards
26+
* @license http://opensource.org/licenses/MIT MIT
27+
*/
28+
class FixturesTest extends TestCase
29+
{
30+
public function testAllFixtures()
31+
{
32+
$fixtures = glob(getenv('FIXTURES_PATH') . DIRECTORY_SEPARATOR . '*.php');
33+
$parser = new FixtureContentParser();
34+
$failures = new \SplStack();
35+
36+
foreach ($fixtures as $fixtureFile) {
37+
$this->validateFixture($fixtureFile, $parser, $failures);
38+
}
39+
40+
/** @var \Throwable $failure */
41+
foreach ($failures as $failure) {
42+
$exception = $failure instanceof \Exception ? $failure : null;
43+
throw new AssertionFailedError($failure->getMessage(), $failure->getCode(), $exception);
44+
}
45+
}
46+
47+
/**
48+
* @param string $fixtureFile
49+
* @param FixtureContentParser $parser
50+
* @param \SplStack $failures
51+
*/
52+
private function validateFixture(
53+
string $fixtureFile,
54+
FixtureContentParser $parser,
55+
\SplStack $failures
56+
) {
57+
58+
$fixtureBasename = basename($fixtureFile);
59+
fwrite(STDOUT, "- Testing fixture '{$fixtureBasename}'...\n");
60+
61+
try {
62+
/**
63+
* @var string $sniffClass
64+
* @var SniffMessages $expected
65+
* @var array $properties
66+
*/
67+
list($sniffClass, $expected, $properties) = $parser->parse($fixtureFile);
68+
69+
$file = $this->createPhpcsForFixture($sniffClass, $fixtureFile, $properties);
70+
$actual = (new SniffMessagesExtractor($file))->extractMessages();
71+
} catch (\Throwable $throwable) {
72+
$failures->push($throwable);
73+
return;
74+
}
75+
76+
$this->validateCodes($expected, $actual, $fixtureBasename, $sniffClass);
77+
$this->validateTotals($expected, $actual, $fixtureBasename, $sniffClass);
78+
}
79+
80+
/**
81+
* @param SniffMessages $expected
82+
* @param SniffMessages $actual
83+
* @param string $fixture
84+
* @param string $sniffClass
85+
*/
86+
private function validateCodes(
87+
SniffMessages $expected,
88+
SniffMessages $actual,
89+
string $fixture,
90+
string $sniffClass
91+
) {
92+
93+
$where = sprintf("in fixture file '%s', line %%d, for sniff '%s'", $fixture, $sniffClass);
94+
95+
foreach ($expected->messages() as $line => $code) {
96+
$actualCode = $actual->messageIn($line);
97+
$this->validateCode('message', $code, sprintf($where, $line), $actualCode);
98+
}
99+
100+
foreach ($expected->warnings() as $line => $code) {
101+
$actualCode = $actual->warningIn($line);
102+
$this->validateCode('warning', $code, sprintf($where, $line), $actualCode);
103+
}
104+
105+
foreach ($expected->errors() as $line => $code) {
106+
$actualCode = $actual->errorIn($line);
107+
$this->validateCode('error', $code, sprintf($where, $line), $actualCode);
108+
}
109+
}
110+
111+
/**
112+
* @param string $type
113+
* @param $code
114+
* @param string $where
115+
* @param string|null $actualCode
116+
*/
117+
private function validateCode(
118+
string $type,
119+
$code,
120+
string $where,
121+
string $actualCode = null
122+
) {
123+
$message = is_string($code)
124+
? sprintf("Expected %s code '%s' was not found", $type, $code)
125+
: sprintf("Expected %s code was not found", $type, $code);
126+
127+
$code === true
128+
? static::assertNotNull($actualCode, "{$message} {$where}.")
129+
: static::assertSame($code, $actualCode, "{$message} {$where}.");
130+
}
131+
132+
/**
133+
* @param SniffMessages $expected
134+
* @param SniffMessages $actual
135+
* @param string $fixtureFile
136+
* @param string $sniffClass
137+
*/
138+
private function validateTotals(
139+
SniffMessages $expected,
140+
SniffMessages $actual,
141+
string $fixtureFile,
142+
string $sniffClass
143+
) {
144+
145+
$expectedTotal = $expected->total();
146+
$actualTotal = $actual->total();
147+
148+
self::assertSame(
149+
$expectedTotal,
150+
$actualTotal,
151+
sprintf(
152+
'Fixture \'%s\', for sniff \'%s\', expected a total of %d messages, '
153+
. 'but actually a total of %d messages found.',
154+
$fixtureFile,
155+
$sniffClass,
156+
$expectedTotal,
157+
$actualTotal
158+
)
159+
);
160+
}
161+
162+
/**
163+
* @param string $sniffName
164+
* @param string $fixtureFile
165+
* @param array $properties
166+
* @return File
167+
* @throws \PHP_CodeSniffer\Exceptions\RuntimeException
168+
* @throws \ReflectionException
169+
*/
170+
private function createPhpcsForFixture(
171+
string $sniffName,
172+
string $fixtureFile,
173+
array $properties
174+
): File {
175+
176+
$sniffName = str_replace('.', DIRECTORY_SEPARATOR, $sniffName) . 'Sniff';
177+
$sniffFile = getenv('SNIFFS_PATH') . DIRECTORY_SEPARATOR . "{$sniffName}.php";
178+
if (!file_exists($sniffFile) || !is_readable($sniffFile)) {
179+
throw new Exception("Non-existent of unreadable sniff file '$sniffFile' found.");
180+
}
181+
182+
$config = new Config();
183+
$config->standards = [];
184+
/** @var Ruleset $ruleset */
185+
$ruleset = (new \ReflectionClass(Ruleset::class))->newInstanceWithoutConstructor();
186+
$ruleset->registerSniffs([$sniffFile], [], []);
187+
$ruleset->populateTokenListeners();
188+
189+
$baseSniffNamespace = getenv('SNIFFS_NAMESPACE');
190+
$sniffFqn = str_replace(DIRECTORY_SEPARATOR, '\\', $sniffName);
191+
foreach ($properties as $name => $value) {
192+
$ruleset->setSniffProperty("{$baseSniffNamespace}\\{$sniffFqn}", $name, $value);
193+
}
194+
195+
return new LocalFile($fixtureFile, $ruleset, $config);
196+
}
197+
}

0 commit comments

Comments
 (0)