Skip to content

Commit 142ad8e

Browse files
committed
Ruleset::__construct(): add tests
1 parent e8edff7 commit 142ad8e

File tree

2 files changed

+299
-0
lines changed

2 files changed

+299
-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: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
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.'MySource' => 'MySource',
120+
$basePath.'PEAR' => 'PEAR',
121+
$basePath.'PSR1' => 'PSR1',
122+
$basePath.'PSR12' => 'PSR12',
123+
$basePath.'PSR2' => 'PSR2',
124+
$basePath.'Squiz' => 'Squiz',
125+
$basePath.'Zend' => 'Zend',
126+
];
127+
128+
$data = [
129+
'Default standards' => [
130+
'cliArgs' => [
131+
'--standard=PSR1',
132+
'--runtime-set installed_paths .',
133+
],
134+
'expected' => $defaultPaths,
135+
],
136+
];
137+
138+
$extraInstalledPath = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'DirectoryExpansion';
139+
$extraInstalledPath .= DIRECTORY_SEPARATOR.'.hiddenAbove'.DIRECTORY_SEPARATOR.'src'.DIRECTORY_SEPARATOR.'MyStandard';
140+
$data['Additional non-namespaced standard'] = [
141+
'cliArgs' => [
142+
'--standard=MyStandard',
143+
'--runtime-set',
144+
'installed_paths',
145+
$extraInstalledPath,
146+
],
147+
'expected' => ($defaultPaths + [$extraInstalledPath => 'MyStandard']),
148+
];
149+
150+
$extraInstalledPath = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'TestStandard';
151+
$data['Additional namespaced standard'] = [
152+
'cliArgs' => [
153+
'--standard=TestStandard',
154+
'--runtime-set',
155+
'installed_paths',
156+
$extraInstalledPath,
157+
// Limit this to a valid sniff to prevent running into error messages unrelated to what
158+
// is being tested here.
159+
'--sniffs=TestStandard.ValidSniffs.RegisterEmptyArray',
160+
],
161+
'expected' => ($defaultPaths + [$extraInstalledPath => 'Fixtures\TestStandard']),
162+
];
163+
164+
return $data;
165+
166+
}//end dataStandardsAreRegisteredWithAutoloader()
167+
168+
169+
/**
170+
* Verify handling of sniff restrictions in combination with the caching setting.
171+
*
172+
* @param array<string> $cliArgs The CLI args to pass to the Config.
173+
* @param bool $cache Whether to turn the cache on or off.
174+
* @param array<string> $expected Sniffs which are expected to have been registered.
175+
*
176+
* @dataProvider dataCachingVersusRestrictions
177+
*
178+
* @return void
179+
*/
180+
public function testCachingVersusRestrictions($cliArgs, $cache, $expected)
181+
{
182+
$config = new ConfigDouble($cliArgs);
183+
184+
// Overrule the cache setting (which is being ignored in the Config when the tests are running).
185+
$config->cache = $cache;
186+
187+
$ruleset = new Ruleset($config);
188+
189+
$actual = array_keys($ruleset->sniffs);
190+
sort($actual);
191+
192+
$this->assertSame($expected, $actual);
193+
194+
}//end testCachingVersusRestrictions()
195+
196+
197+
/**
198+
* Data provider.
199+
*
200+
* Note: the test cases only use `--exclude` to restrict,
201+
*
202+
* @see testCachingVersusRestrictions()
203+
*
204+
* @return array<string, array<string, bool|array<string>>>
205+
*/
206+
public static function dataCachingVersusRestrictions()
207+
{
208+
$completeSet = [
209+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\Files\\ByteOrderMarkSniff',
210+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\NamingConventions\\UpperCaseConstantNameSniff',
211+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\PHP\\DisallowAlternativePHPTagsSniff',
212+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\PHP\\DisallowShortOpenTagSniff',
213+
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Classes\\ClassDeclarationSniff',
214+
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Files\\SideEffectsSniff',
215+
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Methods\\CamelCapsMethodNameSniff',
216+
'PHP_CodeSniffer\\Standards\\Squiz\\Sniffs\\Classes\\ValidClassNameSniff',
217+
];
218+
219+
return [
220+
'No restrictions, cache off' => [
221+
'cliArgs' => ['--standard=PSR1'],
222+
'cache' => false,
223+
'expected' => $completeSet,
224+
],
225+
'Has exclusions, cache off' => [
226+
'cliArgs' => [
227+
'--standard=PSR1',
228+
'--exclude=Generic.Files.ByteOrderMark,Generic.PHP.DisallowShortOpenTag,PSR1.Files.SideEffects,Generic.PHP.DisallowAlternativePHPTags',
229+
],
230+
'cache' => false,
231+
'expected' => [
232+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\NamingConventions\\UpperCaseConstantNameSniff',
233+
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Classes\\ClassDeclarationSniff',
234+
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Methods\\CamelCapsMethodNameSniff',
235+
'PHP_CodeSniffer\\Standards\\Squiz\\Sniffs\\Classes\\ValidClassNameSniff',
236+
],
237+
],
238+
'Has sniff selection, cache off' => [
239+
'cliArgs' => [
240+
'--standard=PSR1',
241+
'--sniffs=Generic.Files.ByteOrderMark,Generic.PHP.DisallowShortOpenTag,PSR1.Files.SideEffects,Generic.PHP.DisallowAlternativePHPTags',
242+
],
243+
'cache' => false,
244+
'expected' => [
245+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\Files\\ByteOrderMarkSniff',
246+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\PHP\\DisallowAlternativePHPTagsSniff',
247+
'PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\PHP\\DisallowShortOpenTagSniff',
248+
'PHP_CodeSniffer\\Standards\\PSR1\\Sniffs\\Files\\SideEffectsSniff',
249+
],
250+
],
251+
'No restrictions, cache on' => [
252+
'cliArgs' => ['--standard=PSR1'],
253+
'cache' => true,
254+
'expected' => $completeSet,
255+
],
256+
'Has exclusions, cache on' => [
257+
'cliArgs' => [
258+
'--standard=PSR1',
259+
'--exclude=Generic.Files.ByteOrderMark,Generic.PHP.DisallowAlternativePHPTags,Generic.PHP.DisallowShortOpenTag,PSR1.Files.SideEffects',
260+
],
261+
'cache' => true,
262+
'expected' => $completeSet,
263+
],
264+
265+
/*
266+
* "Has sniff selection, cache on" case cannot be tested due to the `Ruleset` class
267+
* containing special handling of sniff selection when the tests are running.
268+
*/
269+
270+
];
271+
272+
}//end dataCachingVersusRestrictions()
273+
274+
275+
/**
276+
* Test an exception is thrown when no sniffs have been registered via the ruleset.
277+
*
278+
* @return void
279+
*/
280+
public function testNoSniffsRegisteredException()
281+
{
282+
$standard = __DIR__.'/ConstructorNoSniffsTest.xml';
283+
$config = new ConfigDouble(["--standard=$standard"]);
284+
285+
$message = 'No sniffs were registered';
286+
$this->expectRuntimeExceptionMessage($message);
287+
288+
new Ruleset($config);
289+
290+
}//end testNoSniffsRegisteredException()
291+
292+
293+
}//end class

0 commit comments

Comments
 (0)