Skip to content

Commit cbbd6a1

Browse files
committed
Ruleset::__construct(): add tests
1 parent 20e3427 commit cbbd6a1

File tree

2 files changed

+298
-0
lines changed

2 files changed

+298
-0
lines changed
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="ConstructorTest" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/PHPCSStandards/PHP_CodeSniffer/master/phpcs.xsd">
3+
4+
<file>.</file>
5+
6+
</ruleset>
Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
<?php
2+
/**
3+
* Test the Ruleset::__construct() method.
4+
*
5+
* @author Juliette Reinders Folmer <[email protected]>
6+
* @copyright 2024 PHPCSStandards and contributors
7+
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
8+
*/
9+
10+
namespace PHP_CodeSniffer\Tests\Core\Ruleset;
11+
12+
use PHP_CodeSniffer\Autoload;
13+
use PHP_CodeSniffer\Ruleset;
14+
use PHP_CodeSniffer\Tests\ConfigDouble;
15+
use PHP_CodeSniffer\Tests\Core\Ruleset\AbstractRulesetTestCase;
16+
17+
/**
18+
* Test various aspects of the Ruleset::__construct() method not covered via other tests.
19+
*
20+
* @covers \PHP_CodeSniffer\Ruleset::__construct
21+
*/
22+
final class ConstructorTest extends AbstractRulesetTestCase
23+
{
24+
25+
26+
/**
27+
* Test setting the ruleset name.
28+
*
29+
* @param array<string> $cliArgs The CLI args to pass to the Config.
30+
* @param string $expected The expected set ruleset name.
31+
*
32+
* @dataProvider dataHandlingStandardsPassedViaCLI
33+
*
34+
* @return void
35+
*/
36+
public function testHandlingStandardsPassedViaCLI($cliArgs, $expected)
37+
{
38+
$config = new ConfigDouble($cliArgs);
39+
$ruleset = new Ruleset($config);
40+
41+
$this->assertSame($expected, $ruleset->name);
42+
43+
}//end testHandlingStandardsPassedViaCLI()
44+
45+
46+
/**
47+
* Data provider.
48+
*
49+
* @see testHandlingStandardsPassedViaCLI()
50+
*
51+
* @return array<string, array<string, string|array<string>>>
52+
*/
53+
public static function dataHandlingStandardsPassedViaCLI()
54+
{
55+
return [
56+
'Single standard passed' => [
57+
'cliArgs' => ['--standard=PSR1'],
58+
'expected' => 'PSR1',
59+
],
60+
'Multiple standards passed' => [
61+
'cliArgs' => ['--standard=PSR1,Zend'],
62+
'expected' => 'PSR1, Zend',
63+
],
64+
'Absolute path to standard directory passed' => [
65+
'cliArgs' => [
66+
'--standard='.__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'TestStandard',
67+
// Limit this to a valid sniff to prevent running into error messages unrelated to what
68+
// is being tested here.
69+
'--sniffs=TestStandard.ValidSniffs.RegisterEmptyArray',
70+
],
71+
'expected' => 'TestStandard',
72+
],
73+
];
74+
75+
}//end dataHandlingStandardsPassedViaCLI()
76+
77+
78+
/**
79+
* Verify that standards are registered with the Autoloader.
80+
*
81+
* @param array<string> $cliArgs The CLI args to pass to the Config.
82+
* @param array<string, string> $expected Minimum set of standards expected to be registered with the autoloader.
83+
*
84+
* @dataProvider dataStandardsAreRegisteredWithAutoloader
85+
*
86+
* @return void
87+
*/
88+
public function testStandardsAreRegisteredWithAutoloader($cliArgs, $expected)
89+
{
90+
$config = new ConfigDouble($cliArgs);
91+
new Ruleset($config);
92+
93+
$autoloadPaths = Autoload::getSearchPaths();
94+
95+
// Note: doing a full comparison of the Autoloader registered standards would make this test unstable
96+
// as the `CodeSniffer.conf` of the user running the tests could interfer if they have additional
97+
// external standards registered.
98+
// Also note that `--runtime-set` is being used to set `installed_paths` to prevent making any changes to
99+
// the `CodeSniffer.conf` file of the user running the tests.
100+
foreach ($expected as $path => $namespacedStandardName) {
101+
$this->assertArrayHasKey($path, $autoloadPaths, "Path $path has not been registered with the autoloader");
102+
$this->assertSame($namespacedStandardName, $autoloadPaths[$path], 'Expected (namespaced) standard name does not match');
103+
}
104+
105+
}//end testStandardsAreRegisteredWithAutoloader()
106+
107+
108+
/**
109+
* Data provider.
110+
*
111+
* @see testStandardsAreRegisteredWithAutoloader()
112+
*
113+
* @return array<string, array<string, array<int|string, string>>>
114+
*/
115+
public static function dataStandardsAreRegisteredWithAutoloader()
116+
{
117+
$basePath = dirname(dirname(dirname(__DIR__))).DIRECTORY_SEPARATOR.'src'.DIRECTORY_SEPARATOR.'Standards'.DIRECTORY_SEPARATOR;
118+
$defaultPaths = [
119+
$basePath.'PEAR' => 'PEAR',
120+
$basePath.'PSR1' => 'PSR1',
121+
$basePath.'PSR12' => 'PSR12',
122+
$basePath.'PSR2' => 'PSR2',
123+
$basePath.'Squiz' => 'Squiz',
124+
$basePath.'Zend' => 'Zend',
125+
];
126+
127+
$data = [
128+
'Default standards' => [
129+
'cliArgs' => [
130+
'--standard=PSR1',
131+
'--runtime-set installed_paths .',
132+
],
133+
'expected' => $defaultPaths,
134+
],
135+
];
136+
137+
$extraInstalledPath = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'DirectoryExpansion';
138+
$extraInstalledPath .= DIRECTORY_SEPARATOR.'.hiddenAbove'.DIRECTORY_SEPARATOR.'src'.DIRECTORY_SEPARATOR.'MyStandard';
139+
$data['Additional non-namespaced standard'] = [
140+
'cliArgs' => [
141+
'--standard=MyStandard',
142+
'--runtime-set',
143+
'installed_paths',
144+
$extraInstalledPath,
145+
],
146+
'expected' => ($defaultPaths + [$extraInstalledPath => 'MyStandard']),
147+
];
148+
149+
$extraInstalledPath = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'TestStandard';
150+
$data['Additional namespaced standard'] = [
151+
'cliArgs' => [
152+
'--standard=TestStandard',
153+
'--runtime-set',
154+
'installed_paths',
155+
$extraInstalledPath,
156+
// Limit this to a valid sniff to prevent running into error messages unrelated to what
157+
// is being tested here.
158+
'--sniffs=TestStandard.ValidSniffs.RegisterEmptyArray',
159+
],
160+
'expected' => ($defaultPaths + [$extraInstalledPath => 'Fixtures\TestStandard']),
161+
];
162+
163+
return $data;
164+
165+
}//end dataStandardsAreRegisteredWithAutoloader()
166+
167+
168+
/**
169+
* Verify handling of sniff restrictions in combination with the caching setting.
170+
*
171+
* @param array<string> $cliArgs The CLI args to pass to the Config.
172+
* @param bool $cache Whether to turn the cache on or off.
173+
* @param array<string> $expected Sniffs which are expected to have been registered.
174+
*
175+
* @dataProvider dataCachingVersusRestrictions
176+
*
177+
* @return void
178+
*/
179+
public function testCachingVersusRestrictions($cliArgs, $cache, $expected)
180+
{
181+
$config = new ConfigDouble($cliArgs);
182+
183+
// Overrule the cache setting (which is being ignored in the Config when the tests are running).
184+
$config->cache = $cache;
185+
186+
$ruleset = new Ruleset($config);
187+
188+
$actual = array_keys($ruleset->sniffs);
189+
sort($actual);
190+
191+
$this->assertSame($expected, $actual);
192+
193+
}//end testCachingVersusRestrictions()
194+
195+
196+
/**
197+
* Data provider.
198+
*
199+
* Note: the test cases only use `--exclude` to restrict,
200+
*
201+
* @see testCachingVersusRestrictions()
202+
*
203+
* @return array<string, array<string, bool|array<string>>>
204+
*/
205+
public static function dataCachingVersusRestrictions()
206+
{
207+
$completeSet = [
208+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\Files\\ByteOrderMarkSniff',
209+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\NamingConventions\\UpperCaseConstantNameSniff',
210+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\PHP\\DisallowAlternativePHPTagsSniff',
211+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\PHP\\DisallowShortOpenTagSniff',
212+
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Classes\\ClassDeclarationSniff',
213+
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Files\\SideEffectsSniff',
214+
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Methods\\CamelCapsMethodNameSniff',
215+
'PHP_CodeSniffer\\Standards\\Squiz\\Sniffs\\Classes\\ValidClassNameSniff',
216+
];
217+
218+
return [
219+
'No restrictions, cache off' => [
220+
'cliArgs' => ['--standard=PSR1'],
221+
'cache' => false,
222+
'expected' => $completeSet,
223+
],
224+
'Has exclusions, cache off' => [
225+
'cliArgs' => [
226+
'--standard=PSR1',
227+
'--exclude=Generic.Files.ByteOrderMark,Generic.PHP.DisallowShortOpenTag,PSR1.Files.SideEffects,Generic.PHP.DisallowAlternativePHPTags',
228+
],
229+
'cache' => false,
230+
'expected' => [
231+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\NamingConventions\\UpperCaseConstantNameSniff',
232+
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Classes\\ClassDeclarationSniff',
233+
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Methods\\CamelCapsMethodNameSniff',
234+
'PHP_CodeSniffer\\Standards\\Squiz\\Sniffs\\Classes\\ValidClassNameSniff',
235+
],
236+
],
237+
'Has sniff selection, cache off' => [
238+
'cliArgs' => [
239+
'--standard=PSR1',
240+
'--sniffs=Generic.Files.ByteOrderMark,Generic.PHP.DisallowShortOpenTag,PSR1.Files.SideEffects,Generic.PHP.DisallowAlternativePHPTags',
241+
],
242+
'cache' => false,
243+
'expected' => [
244+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\Files\\ByteOrderMarkSniff',
245+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\PHP\\DisallowAlternativePHPTagsSniff',
246+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\PHP\\DisallowShortOpenTagSniff',
247+
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Files\\SideEffectsSniff',
248+
],
249+
],
250+
'No restrictions, cache on' => [
251+
'cliArgs' => ['--standard=PSR1'],
252+
'cache' => true,
253+
'expected' => $completeSet,
254+
],
255+
'Has exclusions, cache on' => [
256+
'cliArgs' => [
257+
'--standard=PSR1',
258+
'--exclude=Generic.Files.ByteOrderMark,Generic.PHP.DisallowAlternativePHPTags,Generic.PHP.DisallowShortOpenTag,PSR1.Files.SideEffects',
259+
],
260+
'cache' => true,
261+
'expected' => $completeSet,
262+
],
263+
264+
/*
265+
* "Has sniff selection, cache on" case cannot be tested due to the `Ruleset` class
266+
* containing special handling of sniff selection when the tests are running.
267+
*/
268+
269+
];
270+
271+
}//end dataCachingVersusRestrictions()
272+
273+
274+
/**
275+
* Test an exception is thrown when no sniffs have been registered via the ruleset.
276+
*
277+
* @return void
278+
*/
279+
public function testNoSniffsRegisteredException()
280+
{
281+
$standard = __DIR__.'/ConstructorNoSniffsTest.xml';
282+
$config = new ConfigDouble(["--standard=$standard"]);
283+
284+
$message = 'No sniffs were registered';
285+
$this->expectRuntimeExceptionMessage($message);
286+
287+
new Ruleset($config);
288+
289+
}//end testNoSniffsRegisteredException()
290+
291+
292+
}//end class

0 commit comments

Comments
 (0)