@@ -73,9 +73,140 @@ protected function tear_down()
7373 $ this ->removeTestEnvironment ();
7474 }
7575
76+ /**
77+ * Test correctly handling a pre-existing PHPCS configuration file which includes
78+ * a pre-set, valid relative path in `installed_paths`.
79+ *
80+ * @dataProvider dataPHPCSVersions
81+ *
82+ * @param string $phpcsVersion PHPCS version to use in this test.
83+ * This version is randomly selected from the PHPCS versions compatible
84+ * with the PHP version used in the test.
85+ *
86+ * @return void
87+ */
88+ public function testPreexistingValidRelativeInstalledPathsConfigIsKeptIntact ($ phpcsVersion )
89+ {
90+ $ config = $ this ->composerConfig ;
91+ $ config ['require-dev ' ]['squizlabs/php_codesniffer ' ] = $ phpcsVersion ;
92+
93+ $ this ->writeComposerJsonFile ($ config , static ::$ tempLocalPath );
94+
95+ /*
96+ * 1. Install PHPCS and the plugin.
97+ */
98+ $ this ->assertExecute (
99+ sprintf ('composer install -v --working-dir=%s ' , escapeshellarg (static ::$ tempLocalPath )),
100+ 0 , // Expected exit code.
101+ null , // No stdout expectation.
102+ null , // No stderr expectation.
103+ 'Failed to install PHPCS. '
104+ );
105+
106+ /*
107+ * 2. Create a valid standard inside the vendor directory and set it as a relative path.
108+ *
109+ * The standard is placed at "vendor/test-extra-stnd/TestExtraStnd/" so that the relative
110+ * path from the PHPCS install dir (vendor/squizlabs/php_codesniffer) is "../../test-extra-stnd".
111+ */
112+ $ extraStndInVendor = static ::$ tempLocalPath . '/vendor/test-extra-stnd/TestExtraStnd ' ;
113+ $ this ->assertNotFalse (
114+ mkdir ($ extraStndInVendor , 0766 , true ),
115+ "Failed to create the $ extraStndInVendor directory for the test "
116+ );
117+ $ this ->assertDirectoryExists ($ extraStndInVendor );
118+
119+ $ this ->assertNotFalse (
120+ file_put_contents (
121+ $ extraStndInVendor . '/ruleset.xml ' ,
122+ '<?xml version="1.0"?> ' . \PHP_EOL
123+ . '<ruleset name="TestExtraStnd"> ' . \PHP_EOL
124+ . ' <description>Test standard for valid relative path testing.</description> ' . \PHP_EOL
125+ . '</ruleset> ' . \PHP_EOL
126+ ),
127+ 'Failed to create the ruleset.xml fixture file '
128+ );
129+
130+ /*
131+ * Set a valid absolute path first via --config-set, then convert it to a relative path
132+ * by editing the config file directly. This avoids potential PHPCS validation issues
133+ * with relative paths passed to --config-set.
134+ */
135+ $ absoluteStndPath = static ::$ tempLocalPath . '/vendor/test-extra-stnd ' ;
136+ $ relativeStndPath = '../../test-extra-stnd ' ;
137+
138+ $ command = sprintf (
139+ '"vendor/bin/phpcs" --config-set installed_paths %s ' ,
140+ escapeshellarg ($ absoluteStndPath )
141+ );
142+ $ result = $ this ->executeCliCommand ($ command , static ::$ tempLocalPath );
143+ $ this ->assertSame (
144+ 0 ,
145+ $ result ['exitcode ' ],
146+ 'Exitcode for "phpcs --config-set installed_paths" did not match 0 '
147+ );
148+
149+ // Replace the absolute path with a relative path in the config file.
150+ $ confFile = static ::$ tempLocalPath . '/vendor/squizlabs/php_codesniffer/CodeSniffer.conf ' ;
151+ $ confContents = file_get_contents ($ confFile );
152+ $ this ->assertNotFalse ($ confContents , 'Failed to read the PHPCS configuration file ' );
153+ $ confContents = str_replace ($ absoluteStndPath , $ relativeStndPath , $ confContents );
154+ $ this ->assertNotFalse (
155+ file_put_contents ($ confFile , $ confContents ),
156+ 'Failed to write the PHPCS configuration file '
157+ );
158+
159+ // Verify that the config contains the relative path.
160+ $ result = $ this ->executeCliCommand ('"vendor/bin/phpcs" --config-show ' , static ::$ tempLocalPath );
161+ $ this ->assertSame (0 , $ result ['exitcode ' ], 'Exitcode for "phpcs --config-show" did not match 0 (first run) ' );
162+
163+ $ expected = array (
164+ '/test-extra-stnd ' ,
165+ );
166+
167+ $ this ->assertSame (
168+ $ expected ,
169+ $ this ->configShowToPathsArray ($ result ['stdout ' ]),
170+ 'PHPCS configuration does not show the manually set relative installed_paths correctly '
171+ );
172+
173+ /*
174+ * 3. Install an external standard.
175+ */
176+ $ command = sprintf (
177+ 'composer require --dev phpcs-composer-installer/dummy-subdir --no-ansi -v --working-dir=%s ' ,
178+ escapeshellarg (static ::$ tempLocalPath )
179+ );
180+ $ this ->assertExecute (
181+ $ command ,
182+ 0 , // Expected exit code.
183+ 'PHP CodeSniffer Config installed_paths set to ' , // Expectation for stdout.
184+ null , // No stderr expectation.
185+ 'Failed to install Dummy subdir standard. '
186+ );
187+
188+ /*
189+ * Verify that the valid relative path is retained and the new standard is registered correctly.
190+ */
191+ $ result = $ this ->executeCliCommand ('"vendor/bin/phpcs" --config-show ' , static ::$ tempLocalPath );
192+ $ this ->assertSame (0 , $ result ['exitcode ' ], 'Exitcode for "phpcs --config-show" did not match 0 (second run) ' );
193+
194+ $ expected = array (
195+ '/phpcs-composer-installer/dummy-subdir ' ,
196+ '/test-extra-stnd ' ,
197+ );
198+ sort ($ expected , \SORT_NATURAL );
199+
200+ $ this ->assertSame (
201+ $ expected ,
202+ $ this ->configShowToPathsArray ($ result ['stdout ' ]),
203+ 'Paths as updated by the plugin does not contain the expected paths '
204+ );
205+ }
206+
76207 /**
77208 * Test correctly handling a pre-existing PHPCS configuration file which includes a pre-set,
78- * valid `installed_paths`.
209+ * valid absolute path in `installed_paths`.
79210 *
80211 * @dataProvider dataPHPCSVersions
81212 *
@@ -85,7 +216,7 @@ protected function tear_down()
85216 *
86217 * @return void
87218 */
88- public function testPreexistingValidInstalledPathsConfigIsKeptIntact ($ phpcsVersion )
219+ public function testPreexistingValidAbsoluteInstalledPathsConfigIsKeptIntact ($ phpcsVersion )
89220 {
90221 $ config = $ this ->composerConfig ;
91222 $ config ['require-dev ' ]['squizlabs/php_codesniffer ' ] = $ phpcsVersion ;
@@ -163,7 +294,7 @@ public function testPreexistingValidInstalledPathsConfigIsKeptIntact($phpcsVersi
163294
164295 /**
165296 * Test correctly handling a pre-existing PHPCS configuration file which includes both
166- * a pre-set, valid path, as well as an invalid path in `installed_paths`.
297+ * a pre-set, valid path, as well as an invalid relative path in `installed_paths`.
167298 *
168299 * @dataProvider dataPHPCSVersions
169300 *
@@ -173,7 +304,7 @@ public function testPreexistingValidInstalledPathsConfigIsKeptIntact($phpcsVersi
173304 *
174305 * @return void
175306 */
176- public function testPreexistingInvalidInstalledPathsConfigIsRemoved ($ phpcsVersion )
307+ public function testPreexistingInvalidRelativeInstalledPathsConfigIsRemoved ($ phpcsVersion )
177308 {
178309 $ config = $ this ->composerConfig ;
179310 $ config ['require-dev ' ]['squizlabs/php_codesniffer ' ] = $ phpcsVersion ;
@@ -218,13 +349,16 @@ public function testPreexistingInvalidInstalledPathsConfigIsRemoved($phpcsVersio
218349 */
219350 $ confFile = static ::$ tempLocalPath . '/vendor/squizlabs/php_codesniffer/CodeSniffer.conf ' ;
220351 $ confContents = file_get_contents ($ confFile );
221- $ this ->assertNotFalse ($ confContents );
352+ $ this ->assertNotFalse ($ confContents, ' Failed to read the PHPCS configuration file ' );
222353 $ confContents = str_replace (
223354 $ this ->tempExtraStndsSubdir ,
224355 $ this ->tempExtraStndsSubdir . ',path/to/somecloned-stnd ' ,
225356 $ confContents
226357 );
227- $ this ->assertNotFalse (file_put_contents ($ confFile , $ confContents ));
358+ $ this ->assertNotFalse (
359+ file_put_contents ($ confFile , $ confContents ),
360+ 'Failed to write the PHPCS configuration file '
361+ );
228362
229363 // Verify that the config contains the newly set value.
230364 $ result = $ this ->executeCliCommand ('"vendor/bin/phpcs" --config-show ' , static ::$ tempLocalPath );
@@ -277,6 +411,117 @@ public function testPreexistingInvalidInstalledPathsConfigIsRemoved($phpcsVersio
277411 );
278412 }
279413
414+ /**
415+ * Test correctly handling a pre-existing PHPCS configuration file which includes both
416+ * a pre-set, valid path, as well as an invalid absolute path in `installed_paths`.
417+ *
418+ * @dataProvider dataPHPCSVersions
419+ *
420+ * @param string $phpcsVersion PHPCS version to use in this test.
421+ * This version is randomly selected from the PHPCS versions compatible
422+ * with the PHP version used in the test.
423+ *
424+ * @return void
425+ */
426+ public function testPreexistingInvalidAbsoluteInstalledPathsConfigIsRemoved ($ phpcsVersion )
427+ {
428+ $ config = $ this ->composerConfig ;
429+ $ config ['require-dev ' ]['squizlabs/php_codesniffer ' ] = $ phpcsVersion ;
430+
431+ $ this ->writeComposerJsonFile ($ config , static ::$ tempLocalPath );
432+
433+ /*
434+ * 1. Install PHPCS and the plugin.
435+ */
436+ $ this ->assertExecute (
437+ sprintf ('composer install -v --working-dir=%s ' , escapeshellarg (static ::$ tempLocalPath )),
438+ 0 , // Expected exit code.
439+ null , // No stdout expectation.
440+ null , // No stderr expectation.
441+ 'Failed to install PHPCS. '
442+ );
443+
444+ /*
445+ * 2. Set the installed_paths and verify it is registered correctly.
446+ */
447+ $ command = sprintf (
448+ '"vendor/bin/phpcs" --config-set installed_paths %s ' ,
449+ escapeshellarg ($ this ->tempExtraStndsPath )
450+ );
451+ $ result = $ this ->executeCliCommand ($ command , static ::$ tempLocalPath );
452+ $ this ->assertSame (
453+ 0 ,
454+ $ result ['exitcode ' ],
455+ 'Exitcode for "phpcs --config-set installed_paths" did not match 0 '
456+ );
457+
458+ /*
459+ * Manipulate the value of installed_paths to add an invalid absolute path.
460+ */
461+ $ confFile = static ::$ tempLocalPath . '/vendor/squizlabs/php_codesniffer/CodeSniffer.conf ' ;
462+ $ confContents = file_get_contents ($ confFile );
463+ $ this ->assertNotFalse ($ confContents , 'Failed to read the PHPCS configuration file ' );
464+ $ confContents = str_replace (
465+ $ this ->tempExtraStndsSubdir ,
466+ $ this ->tempExtraStndsSubdir . ',/nonexistent/absolute/path/to/standard ' ,
467+ $ confContents
468+ );
469+ $ this ->assertNotFalse (
470+ file_put_contents ($ confFile , $ confContents ),
471+ 'Failed to write the PHPCS configuration file '
472+ );
473+
474+ // Verify that the config contains the newly set value.
475+ $ result = $ this ->executeCliCommand ('"vendor/bin/phpcs" --config-show ' , static ::$ tempLocalPath );
476+ $ this ->assertSame (0 , $ result ['exitcode ' ], 'Exitcode for "phpcs --config-show" did not match 0 (first run) ' );
477+
478+ $ expected = array (
479+ $ this ->tempExtraStndsPath ,
480+ '/nonexistent/absolute/path/to/standard ' ,
481+ );
482+ sort ($ expected , \SORT_NATURAL );
483+
484+ $ this ->assertSame (
485+ $ expected ,
486+ $ this ->configShowToPathsArray ($ result ['stdout ' ]),
487+ 'PHPCS configuration does not show the manually set installed_paths correctly '
488+ );
489+
490+ /*
491+ * 3. Install an external standard.
492+ */
493+ $ command = sprintf (
494+ 'composer require --dev phpcs-composer-installer/dummy-subdir --no-ansi -v --working-dir=%s ' ,
495+ escapeshellarg (static ::$ tempLocalPath )
496+ );
497+ $ this ->assertExecute (
498+ $ command ,
499+ 0 , // Expected exit code.
500+ 'PHP CodeSniffer Config installed_paths set to ' , // Expectation for stdout.
501+ null , // No stderr expectation.
502+ 'Failed to install Dummy subdir standard. '
503+ );
504+
505+ /*
506+ * Verify that the valid preset path is retained, that the invalid absolute path is removed
507+ * and the new standard is registered correctly.
508+ */
509+ $ result = $ this ->executeCliCommand ('"vendor/bin/phpcs" --config-show ' , static ::$ tempLocalPath );
510+ $ this ->assertSame (0 , $ result ['exitcode ' ], 'Exitcode for "phpcs --config-show" did not match 0 (second run) ' );
511+
512+ $ expected = array (
513+ $ this ->tempExtraStndsPath ,
514+ '/phpcs-composer-installer/dummy-subdir ' ,
515+ );
516+ sort ($ expected , \SORT_NATURAL );
517+
518+ $ this ->assertSame (
519+ $ expected ,
520+ $ this ->configShowToPathsArray ($ result ['stdout ' ]),
521+ 'Paths as updated by the plugin does not contain the expected paths '
522+ );
523+ }
524+
280525 /**
281526 * Data provider.
282527 *
0 commit comments