Skip to content

Commit

Permalink
Ruleset::processRuleset(): add tests for handling <autoload> direct…
Browse files Browse the repository at this point in the history
…ives (#715)

Add tests specifically aimed at verifying `<autoload>` elements are read and handled correctly.

Note: as `autoload` directive are not stored in the ruleset, but directly lead to a file include using `include_once`, these tests need to run in a separate process to circumvent the possibility of test cross-contamination.
  • Loading branch information
jrfnl committed Dec 2, 2024
1 parent 6d090da commit 783f880
Show file tree
Hide file tree
Showing 9 changed files with 257 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
/**
* Test fixture.
*
* This file is only used to check whether it has been `include`d.
*
* @see \PHP_CodeSniffer\Tests\Core\Ruleset\ProcessRulesetAutoloadTest
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
/**
* Test fixture.
*
* This file is only used to check whether it has been `include`d.
*
* @see \PHP_CodeSniffer\Tests\Core\Ruleset\ProcessRulesetAutoloadTest
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
/**
* Test fixture.
*
* This file is only used to check whether it has been `include`d.
*
* @see \PHP_CodeSniffer\Tests\Core\Ruleset\ProcessRulesetAutoloadTest
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
/**
* Test fixture.
*
* This file is only used to check whether it has been `include`d.
*
* @see \PHP_CodeSniffer\Tests\Core\Ruleset\ProcessRulesetAutoloadTest
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
/**
* Test fixture.
*
* This file is only used to check whether it has been `include`d.
*
* @see \PHP_CodeSniffer\Tests\Core\Ruleset\ProcessRulesetAutoloadTest
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
/**
* Test fixture.
*
* This file is only used to check whether it has been `include`d.
*
* @see \PHP_CodeSniffer\Tests\Core\Ruleset\ProcessRulesetAutoloadTest
*/
8 changes: 8 additions & 0 deletions tests/Core/Ruleset/ProcessRulesetAutoloadFileNotFoundTest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="ProcessRulesetAutoloadTest" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/PHPCSStandards/PHP_CodeSniffer/master/phpcs.xsd">

<autoload>./tests/Core/Ruleset/Fixtures/ThisFileDoesNotExist.php</autoload>

<!-- Prevent a "no sniff were registered" error. -->
<rule ref="Generic.PHP.BacktickOperator"/>
</ruleset>
164 changes: 164 additions & 0 deletions tests/Core/Ruleset/ProcessRulesetAutoloadTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<?php
/**
* Test handling of <autoload> instructions.
*
* @author Juliette Reinders Folmer <[email protected]>
* @copyright 2024 PHPCSStandards and contributors
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/

namespace PHP_CodeSniffer\Tests\Core\Ruleset;

use PHP_CodeSniffer\Ruleset;
use PHP_CodeSniffer\Tests\ConfigDouble;
use PHP_CodeSniffer\Tests\Core\Ruleset\AbstractRulesetTestCase;

/**
* Test handling of <autoload> instructions.
*
* Note: these tests need to run in separate processes as otherwise we cannot
* reliably determine whether or not the correct files were loaded as the
* underlying code uses `include_once`.
*
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*
* @covers \PHP_CodeSniffer\Ruleset::processRuleset
*/
final class ProcessRulesetAutoloadTest extends AbstractRulesetTestCase
{


/**
* Verify that in CS mode, phpcs-only <autoload> directives are respected and phpcbf-only <autoload>
* directives are ignored.
*
* @return void
*/
public function testShouldProcessAutoloadCsonly()
{
if (PHP_CODESNIFFER_CBF === true) {
$this->markTestSkipped('This test needs CS mode to run');
}

$originallyIncludes = get_included_files();

// Set up the ruleset.
$standard = __DIR__.'/ProcessRulesetAutoloadTest.xml';
$config = new ConfigDouble(["--standard=$standard"]);
new Ruleset($config);

$finalIncludes = get_included_files();
$diff = array_diff($finalIncludes, $originallyIncludes);

$this->assertContains(
__DIR__.str_replace('/', DIRECTORY_SEPARATOR, '/Fixtures/ProcessRulesetAutoloadLoadAlways.1.php'),
$diff,
'ProcessRulesetAutoloadLoadAlways.1.php autoload file was not loaded'
);
$this->assertContains(
__DIR__.str_replace('/', DIRECTORY_SEPARATOR, '/Fixtures/ProcessRulesetAutoloadLoadAlways.2.php'),
$diff,
'ProcessRulesetAutoloadLoadAlways.2.php autoload file was not loaded'
);
$this->assertContains(
__DIR__.str_replace('/', DIRECTORY_SEPARATOR, '/Fixtures/ProcessRulesetAutoloadLoadAlways.3.php'),
$diff,
'ProcessRulesetAutoloadLoadAlways.3.php autoload file was not loaded'
);
$this->assertContains(
__DIR__.str_replace('/', DIRECTORY_SEPARATOR, '/Fixtures/ProcessRulesetAutoloadLoadAlways.4.php'),
$diff,
'ProcessRulesetAutoloadLoadAlways.4.php autoload file was not loaded'
);
$this->assertContains(
__DIR__.str_replace('/', DIRECTORY_SEPARATOR, '/Fixtures/ProcessRulesetAutoloadLoadPhpcsOnly.php'),
$diff,
'ProcessRulesetAutoloadLoadPhpcsOnly.php autoload file was not loaded'
);
$this->assertNotContains(
__DIR__.str_replace('/', DIRECTORY_SEPARATOR, '/Fixtures/ProcessRulesetAutoloadLoadPhpcbfOnly.php'),
$diff,
'ProcessRulesetAutoloadLoadPhpcbfOnly.php autoload file was loaded, while it shouldn\'t have been'
);

}//end testShouldProcessAutoloadCsonly()


/**
* Verify that in CBF mode, phpcbf-only <autoload> directives are respected and phpcs-only <autoload>
* directives are ignored.
*
* @group CBF
*
* @return void
*/
public function testShouldProcessAutoloadCbfonly()
{
if (PHP_CODESNIFFER_CBF === false) {
$this->markTestSkipped('This test needs CBF mode to run');
}

$originallyIncludes = get_included_files();

// Set up the ruleset.
$standard = __DIR__.'/ProcessRulesetAutoloadTest.xml';
$config = new ConfigDouble(["--standard=$standard"]);
new Ruleset($config);

$finalIncludes = get_included_files();
$diff = array_diff($finalIncludes, $originallyIncludes);

$this->assertContains(
__DIR__.str_replace('/', DIRECTORY_SEPARATOR, '/Fixtures/ProcessRulesetAutoloadLoadAlways.1.php'),
$diff,
'ProcessRulesetAutoloadLoadAlways.1.php autoload file was not loaded'
);
$this->assertContains(
__DIR__.str_replace('/', DIRECTORY_SEPARATOR, '/Fixtures/ProcessRulesetAutoloadLoadAlways.2.php'),
$diff,
'ProcessRulesetAutoloadLoadAlways.2.php autoload file was not loaded'
);
$this->assertContains(
__DIR__.str_replace('/', DIRECTORY_SEPARATOR, '/Fixtures/ProcessRulesetAutoloadLoadAlways.3.php'),
$diff,
'ProcessRulesetAutoloadLoadAlways.3.php autoload file was not loaded'
);
$this->assertContains(
__DIR__.str_replace('/', DIRECTORY_SEPARATOR, '/Fixtures/ProcessRulesetAutoloadLoadAlways.4.php'),
$diff,
'ProcessRulesetAutoloadLoadAlways.4.php autoload file was not loaded'
);
$this->assertNotContains(
__DIR__.str_replace('/', DIRECTORY_SEPARATOR, '/Fixtures/ProcessRulesetAutoloadLoadPhpcsOnly.php'),
$diff,
'ProcessRulesetAutoloadLoadPhpcsOnly.php autoload file was loaded, while it shouldn\'t have been'
);
$this->assertContains(
__DIR__.str_replace('/', DIRECTORY_SEPARATOR, '/Fixtures/ProcessRulesetAutoloadLoadPhpcbfOnly.php'),
$diff,
'ProcessRulesetAutoloadLoadPhpcbfOnly.php autoload file was not loaded'
);

}//end testShouldProcessAutoloadCbfonly()


/**
* Test an exception is thrown when the <autoload> directive points to a file which doesn't exist.
*
* @return void
*/
public function testFileNotFoundException()
{
$exceptionMsg = 'The specified autoload file "./tests/Core/Ruleset/Fixtures/ThisFileDoesNotExist.php" does not exist';
$this->expectRuntimeExceptionMessage($exceptionMsg);

// Set up the ruleset.
$standard = __DIR__.'/ProcessRulesetAutoloadFileNotFoundTest.xml';
$config = new ConfigDouble(["--standard=$standard"]);
new Ruleset($config);

}//end testFileNotFoundException()


}//end class
37 changes: 37 additions & 0 deletions tests/Core/Ruleset/ProcessRulesetAutoloadTest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="ProcessRulesetAutoloadTest" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/PHPCSStandards/PHP_CodeSniffer/master/phpcs.xsd">

<file>.</file>

<!--
###############################################
# Neither set. #
# Testing various ways paths can be provided. #
###############################################
-->
<!-- Path relative to directory containing the ruleset. -->
<autoload>./Fixtures/ProcessRulesetAutoloadLoadAlways.1.php</autoload>
<autoload>Fixtures/ProcessRulesetAutoloadLoadAlways.2.php</autoload>

<!-- Path relative to command directory. -->
<autoload>./tests/Core/Ruleset/Fixtures/ProcessRulesetAutoloadLoadAlways.3.php</autoload>
<autoload>tests/Core/Ruleset/Fixtures/ProcessRulesetAutoloadLoadAlways.4.php</autoload>

<!--
###################
# phpcs-only set. #
###################
-->
<autoload phpcs-only="true">./tests/Core/Ruleset/Fixtures/ProcessRulesetAutoloadLoadPhpcsOnly.php</autoload>

<!--
####################
# phpcbf-only set. #
####################
-->
<autoload phpcbf-only="true">./tests/Core/Ruleset/Fixtures/ProcessRulesetAutoloadLoadPhpcbfOnly.php</autoload>


<!-- Prevent a "no sniff were registered" error. -->
<rule ref="Generic.PHP.BacktickOperator"/>
</ruleset>

0 comments on commit 783f880

Please sign in to comment.