diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml index 80c4690430..511a12dd47 100644 --- a/.markdownlint-cli2.yaml +++ b/.markdownlint-cli2.yaml @@ -19,6 +19,7 @@ showFound: true ignores: - "node_modules/" - "vendor/" + - "tests/Core/Generators/Expectations/" # Disable inline config comments. noInlineConfig: true diff --git a/src/Generators/HTML.php b/src/Generators/HTML.php index 2a4a8076da..cab4abfd91 100644 --- a/src/Generators/HTML.php +++ b/src/Generators/HTML.php @@ -133,7 +133,7 @@ protected function printHeader() echo ''.PHP_EOL; echo ' '.PHP_EOL; echo " $standard Coding Standards".PHP_EOL; - echo ' '.self::STYLESHEET.PHP_EOL; + echo ' '.str_replace("\n", PHP_EOL, self::STYLESHEET).PHP_EOL; echo ' '.PHP_EOL; echo ' '.PHP_EOL; echo "

$standard Coding Standards

".PHP_EOL; @@ -226,6 +226,9 @@ protected function printTextBlock(DOMNode $node) $content = trim($node->nodeValue); $content = htmlspecialchars($content); + // Use the correct line endings based on the OS. + $content = str_replace("\n", PHP_EOL, $content); + // Allow em tags only. $content = str_replace('<em>', '', $content); $content = str_replace('</em>', '', $content); diff --git a/src/Generators/Markdown.php b/src/Generators/Markdown.php index a9839a81a4..40fccd222a 100644 --- a/src/Generators/Markdown.php +++ b/src/Generators/Markdown.php @@ -111,6 +111,9 @@ protected function printTextBlock(DOMNode $node) $content = trim($node->nodeValue); $content = htmlspecialchars($content); + // Use the correct line endings based on the OS. + $content = str_replace("\n", PHP_EOL, $content); + $content = str_replace('<em>', '*', $content); $content = str_replace('</em>', '*', $content); @@ -132,13 +135,13 @@ protected function printCodeComparisonBlock(DOMNode $node) $firstTitle = $codeBlocks->item(0)->getAttribute('title'); $first = trim($codeBlocks->item(0)->nodeValue); - $first = str_replace("\n", "\n ", $first); + $first = str_replace("\n", PHP_EOL.' ', $first); $first = str_replace('', '', $first); $first = str_replace('', '', $first); $secondTitle = $codeBlocks->item(1)->getAttribute('title'); $second = trim($codeBlocks->item(1)->nodeValue); - $second = str_replace("\n", "\n ", $second); + $second = str_replace("\n", PHP_EOL.' ', $second); $second = str_replace('', '', $second); $second = str_replace('', '', $second); diff --git a/tests/Core/Generators/Expectations/ExpectedOutputEmpty.txt b/tests/Core/Generators/Expectations/ExpectedOutputEmpty.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/Core/Generators/Expectations/ExpectedOutputNoDocs.html b/tests/Core/Generators/Expectations/ExpectedOutputNoDocs.html new file mode 100644 index 0000000000..060de7aa63 --- /dev/null +++ b/tests/Core/Generators/Expectations/ExpectedOutputNoDocs.html @@ -0,0 +1,78 @@ + + + GeneratorTest Coding Standards + + + +

GeneratorTest Coding Standards

+

Table of Contents

+ +
Documentation generated on #REDACTED# by PHP_CodeSniffer #VERSION#
+ + diff --git a/tests/Core/Generators/Expectations/ExpectedOutputNoDocs.md b/tests/Core/Generators/Expectations/ExpectedOutputNoDocs.md new file mode 100644 index 0000000000..ece2692187 --- /dev/null +++ b/tests/Core/Generators/Expectations/ExpectedOutputNoDocs.md @@ -0,0 +1,2 @@ +# GeneratorTest Coding Standard +Documentation generated on *REDACTED* by [PHP_CodeSniffer *VERSION*](https://github.com/PHPCSStandards/PHP_CodeSniffer) diff --git a/tests/Core/Generators/Expectations/ExpectedOutputOneDoc.html b/tests/Core/Generators/Expectations/ExpectedOutputOneDoc.html new file mode 100644 index 0000000000..772d3861ec --- /dev/null +++ b/tests/Core/Generators/Expectations/ExpectedOutputOneDoc.html @@ -0,0 +1,82 @@ + + + GeneratorTest Coding Standards + + + +

GeneratorTest Coding Standards

+

Table of Contents

+ + +

One Standard Block, No Code

+

Documentation contains one standard block and no code comparison.

+
Documentation generated on #REDACTED# by PHP_CodeSniffer #VERSION#
+ + diff --git a/tests/Core/Generators/Expectations/ExpectedOutputOneDoc.md b/tests/Core/Generators/Expectations/ExpectedOutputOneDoc.md new file mode 100644 index 0000000000..f8deb0ce20 --- /dev/null +++ b/tests/Core/Generators/Expectations/ExpectedOutputOneDoc.md @@ -0,0 +1,5 @@ +# GeneratorTest Coding Standard + +## One Standard Block, No Code +Documentation contains one standard block and no code comparison. +Documentation generated on *REDACTED* by [PHP_CodeSniffer *VERSION*](https://github.com/PHPCSStandards/PHP_CodeSniffer) diff --git a/tests/Core/Generators/Expectations/ExpectedOutputOneDoc.txt b/tests/Core/Generators/Expectations/ExpectedOutputOneDoc.txt new file mode 100644 index 0000000000..75bbdcb003 --- /dev/null +++ b/tests/Core/Generators/Expectations/ExpectedOutputOneDoc.txt @@ -0,0 +1,7 @@ + +-------------------------------------------------------------- +| GENERATORTEST CODING STANDARD: ONE STANDARD BLOCK, NO CODE | +-------------------------------------------------------------- + +Documentation contains one standard block and no code comparison. + diff --git a/tests/Core/Generators/Expectations/ExpectedOutputStructureDocs.html b/tests/Core/Generators/Expectations/ExpectedOutputStructureDocs.html new file mode 100644 index 0000000000..b17d05212a --- /dev/null +++ b/tests/Core/Generators/Expectations/ExpectedOutputStructureDocs.html @@ -0,0 +1,178 @@ + + + GeneratorTest Coding Standards + + + +

GeneratorTest Coding Standards

+

Table of Contents

+ + +

No Content

+
+

One Standard Block, Code Comparison

+

Documentation contains one standard block and one code comparison.

+ + + + + + + + + +
Valid: Lorem ipsum dolor sit amet.Invalid: Maecenas non rutrum dolor.
class Code {}class Comparison {}
+
+

One Standard Block, No Code

+

Documentation contains one standard block and no code comparison.

+
+

One Standard Block, Two Code Comparisons

+

Documentation contains one standard block and two code comparisons.

+ + + + + + + + + +
Valid: Etiam commodo magna at vestibulum blandit.Invalid: Vivamus lacinia ante velit.
class Code {}class Comparison {}
+ + + + + + + + + +
Valid: Pellentesque nisi neque.Invalid: Mauris dictum metus quis maximus pharetra.
$one = 10;$a = 10;
+
+

Two Standard Blocks, No Code

+

This is standard block one.

+

This is standard block two.

+
+

Two Standard Blocks, One Code Comparison

+

This is standard block one.

+ + + + + + + + + +
Valid: Vestibulum et orci condimentum.Invalid: Donec in nisl ut tortor convallis interdum.
class Code {}class Comparison {}
+

This is standard block two.

+
+

Two Standard Blocks, Three Code Comparisons

+

This is standard block one.

+ + + + + + + + + +
Valid: Vestibulum et orci condimentum.Invalid: Donec in nisl ut tortor convallis interdum.
class Code {}class Comparison {}
+

This is standard block two.

+ + + + + + + + + +
Valid: Pellentesque nisi neque.Invalid: Mauris dictum metus quis maximus pharetra.
$one = 10;$a = 10;
+ + + + + + + + + +
Valid: Quisque sagittis nisi vitae.Invalid: Morbi ac libero vitae lorem.
echo $foo;print $foo;
+
Documentation generated on #REDACTED# by PHP_CodeSniffer #VERSION#
+ + diff --git a/tests/Core/Generators/Expectations/ExpectedOutputStructureDocs.md b/tests/Core/Generators/Expectations/ExpectedOutputStructureDocs.md new file mode 100644 index 0000000000..9b80a5e063 --- /dev/null +++ b/tests/Core/Generators/Expectations/ExpectedOutputStructureDocs.md @@ -0,0 +1,151 @@ +# GeneratorTest Coding Standard + +## No Content + +## One Standard Block, Code Comparison +Documentation contains one standard block and one code comparison. + + + + + + + + + +
Valid: Lorem ipsum dolor sit amet.Invalid: Maecenas non rutrum dolor.
+ + class Code {} + + + + class Comparison {} + +
+ +## One Standard Block, No Code +Documentation contains one standard block and no code comparison. + +## One Standard Block, Two Code Comparisons +Documentation contains one standard block and two code comparisons. + + + + + + + + + +
Valid: Etiam commodo magna at vestibulum blandit.Invalid: Vivamus lacinia ante velit.
+ + class Code {} + + + + class Comparison {} + +
+ + + + + + + + + +
Valid: Pellentesque nisi neque.Invalid: Mauris dictum metus quis maximus pharetra.
+ + $one = 10; + + + + $a = 10; + +
+ +## Two Standard Blocks, No Code +This is standard block one. +This is standard block two. + +## Two Standard Blocks, One Code Comparison +This is standard block one. + + + + + + + + + +
Valid: Vestibulum et orci condimentum.Invalid: Donec in nisl ut tortor convallis interdum.
+ + class Code {} + + + + class Comparison {} + +
+This is standard block two. + +## Two Standard Blocks, Three Code Comparisons +This is standard block one. + + + + + + + + + +
Valid: Vestibulum et orci condimentum.Invalid: Donec in nisl ut tortor convallis interdum.
+ + class Code {} + + + + class Comparison {} + +
+This is standard block two. + + + + + + + + + +
Valid: Pellentesque nisi neque.Invalid: Mauris dictum metus quis maximus pharetra.
+ + $one = 10; + + + + $a = 10; + +
+ + + + + + + + + +
Valid: Quisque sagittis nisi vitae.Invalid: Morbi ac libero vitae lorem.
+ + echo $foo; + + + + print $foo; + +
+Documentation generated on *REDACTED* by [PHP_CodeSniffer *VERSION*](https://github.com/PHPCSStandards/PHP_CodeSniffer) diff --git a/tests/Core/Generators/Expectations/ExpectedOutputStructureDocs.txt b/tests/Core/Generators/Expectations/ExpectedOutputStructureDocs.txt new file mode 100644 index 0000000000..44b402955a --- /dev/null +++ b/tests/Core/Generators/Expectations/ExpectedOutputStructureDocs.txt @@ -0,0 +1,100 @@ + +--------------------------------------------- +| GENERATORTEST CODING STANDARD: NO CONTENT | +--------------------------------------------- + + +---------------------------------------------------------------------- +| GENERATORTEST CODING STANDARD: ONE STANDARD BLOCK, CODE COMPARISON | +---------------------------------------------------------------------- + +Documentation contains one standard block and one code comparison. + +----------------------------------------- CODE COMPARISON ------------------------------------------ +| Valid: Lorem ipsum dolor sit amet. | Invalid: Maecenas non rutrum dolor. | +---------------------------------------------------------------------------------------------------- +| class Code {} | class Comparison {} | +---------------------------------------------------------------------------------------------------- + + +-------------------------------------------------------------- +| GENERATORTEST CODING STANDARD: ONE STANDARD BLOCK, NO CODE | +-------------------------------------------------------------- + +Documentation contains one standard block and no code comparison. + + +--------------------------------------------------------------------------- +| GENERATORTEST CODING STANDARD: ONE STANDARD BLOCK, TWO CODE COMPARISONS | +--------------------------------------------------------------------------- + +Documentation contains one standard block and two code comparisons. + +----------------------------------------- CODE COMPARISON ------------------------------------------ +| Valid: Etiam commodo magna at vestibulum | Invalid: Vivamus lacinia ante velit. | +| blandit. | | +---------------------------------------------------------------------------------------------------- +| class Code {} | class Comparison {} | +---------------------------------------------------------------------------------------------------- + +----------------------------------------- CODE COMPARISON ------------------------------------------ +| Valid: Pellentesque nisi neque. | Invalid: Mauris dictum metus quis maximus | +| | pharetra. | +---------------------------------------------------------------------------------------------------- +| $one = 10; | $a = 10; | +---------------------------------------------------------------------------------------------------- + + +--------------------------------------------------------------- +| GENERATORTEST CODING STANDARD: TWO STANDARD BLOCKS, NO CODE | +--------------------------------------------------------------- + +This is standard block one. + +This is standard block two. + + +--------------------------------------------------------------------------- +| GENERATORTEST CODING STANDARD: TWO STANDARD BLOCKS, ONE CODE COMPARISON | +--------------------------------------------------------------------------- + +This is standard block one. + +----------------------------------------- CODE COMPARISON ------------------------------------------ +| Valid: Vestibulum et orci condimentum. | Invalid: Donec in nisl ut tortor convallis | +| | interdum. | +---------------------------------------------------------------------------------------------------- +| class Code {} | class Comparison {} | +---------------------------------------------------------------------------------------------------- + +This is standard block two. + + +------------------------------------------------------------------------------ +| GENERATORTEST CODING STANDARD: TWO STANDARD BLOCKS, THREE CODE COMPARISONS | +------------------------------------------------------------------------------ + +This is standard block one. + +----------------------------------------- CODE COMPARISON ------------------------------------------ +| Valid: Vestibulum et orci condimentum. | Invalid: Donec in nisl ut tortor convallis | +| | interdum. | +---------------------------------------------------------------------------------------------------- +| class Code {} | class Comparison {} | +---------------------------------------------------------------------------------------------------- + +This is standard block two. + +----------------------------------------- CODE COMPARISON ------------------------------------------ +| Valid: Pellentesque nisi neque. | Invalid: Mauris dictum metus quis maximus | +| | pharetra. | +---------------------------------------------------------------------------------------------------- +| $one = 10; | $a = 10; | +---------------------------------------------------------------------------------------------------- + +----------------------------------------- CODE COMPARISON ------------------------------------------ +| Valid: Quisque sagittis nisi vitae. | Invalid: Morbi ac libero vitae lorem. | +---------------------------------------------------------------------------------------------------- +| echo $foo; | print $foo; | +---------------------------------------------------------------------------------------------------- + diff --git a/tests/Core/Generators/Fixtures/HTMLDouble.php b/tests/Core/Generators/Fixtures/HTMLDouble.php new file mode 100644 index 0000000000..cb327efe42 --- /dev/null +++ b/tests/Core/Generators/Fixtures/HTMLDouble.php @@ -0,0 +1,46 @@ + + * @copyright 2024 Juliette Reinders Folmer. All rights reserved. + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Tests\Core\Generators\Fixtures; + +use PHP_CodeSniffer\Generators\HTML; + +class HTMLDouble extends HTML +{ + + /** + * Print the footer of the HTML page without the date or version nr to make the expectation fixtures stable. + * + * @return void + */ + protected function printFooter() + { + // Turn off errors so we don't get timezone warnings if people + // don't have their timezone set. + $errorLevel = error_reporting(0); + echo '
'; + echo 'Documentation generated on #REDACTED#'; + echo ' by PHP_CodeSniffer #VERSION#'; + echo '
'.PHP_EOL; + error_reporting($errorLevel); + + echo ' '.PHP_EOL; + echo ''.PHP_EOL; + } + + /** + * Print the _real_ footer of the HTML page. + * + * @return void + */ + public function printRealFooter() + { + parent::printFooter(); + } +} diff --git a/tests/Core/Generators/Fixtures/MarkdownDouble.php b/tests/Core/Generators/Fixtures/MarkdownDouble.php new file mode 100644 index 0000000000..2b03c277bb --- /dev/null +++ b/tests/Core/Generators/Fixtures/MarkdownDouble.php @@ -0,0 +1,40 @@ + + * @copyright 2024 Juliette Reinders Folmer. All rights reserved. + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Tests\Core\Generators\Fixtures; + +use PHP_CodeSniffer\Generators\Markdown; + +class MarkdownDouble extends Markdown +{ + + /** + * Print the markdown footer without the date or version nr to make the expectation fixtures stable. + * + * @return void + */ + protected function printFooter() + { + // Turn off errors so we don't get timezone warnings if people + // don't have their timezone set. + error_reporting(0); + echo 'Documentation generated on *REDACTED*'; + echo ' by [PHP_CodeSniffer *VERSION*](https://github.com/PHPCSStandards/PHP_CodeSniffer)'.PHP_EOL; + } + + /** + * Print the _real_ footer of the markdown page. + * + * @return void + */ + public function printRealFooter() + { + parent::printFooter(); + } +} diff --git a/tests/Core/Generators/Fixtures/MockGenerator.php b/tests/Core/Generators/Fixtures/MockGenerator.php new file mode 100644 index 0000000000..43534180a6 --- /dev/null +++ b/tests/Core/Generators/Fixtures/MockGenerator.php @@ -0,0 +1,29 @@ + + * @copyright 2024 Juliette Reinders Folmer. All rights reserved. + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Tests\Core\Generators\Fixtures; + +use DOMNode; +use PHP_CodeSniffer\Generators\Generator; + +class MockGenerator extends Generator +{ + + /** + * Process the documentation for a single sniff. + * + * @param \DOMNode $doc The DOMNode object for the sniff. + * + * @return void + */ + protected function processSniff(DOMNode $doc) + { + echo $this->getTitle($doc), PHP_EOL; + } +} diff --git a/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/NoContentStandard.xml b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/NoContentStandard.xml new file mode 100644 index 0000000000..83afee8e83 --- /dev/null +++ b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/NoContentStandard.xml @@ -0,0 +1,2 @@ + + diff --git a/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/NoDocumentationElementStandard.xml b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/NoDocumentationElementStandard.xml new file mode 100644 index 0000000000..ca8290f1b4 --- /dev/null +++ b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/NoDocumentationElementStandard.xml @@ -0,0 +1,2 @@ + + diff --git a/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/OneStandardBlockCodeComparisonStandard.xml b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/OneStandardBlockCodeComparisonStandard.xml new file mode 100644 index 0000000000..c3ce35cd71 --- /dev/null +++ b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/OneStandardBlockCodeComparisonStandard.xml @@ -0,0 +1,19 @@ + + + + + + + class Code {} + ]]> + + + class Comparison {} + ]]> + + + diff --git a/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/OneStandardBlockNoCodeStandard.xml b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/OneStandardBlockNoCodeStandard.xml new file mode 100644 index 0000000000..fc014949e7 --- /dev/null +++ b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/OneStandardBlockNoCodeStandard.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/OneStandardBlockTwoCodeComparisonsStandard.xml b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/OneStandardBlockTwoCodeComparisonsStandard.xml new file mode 100644 index 0000000000..19559e6720 --- /dev/null +++ b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/OneStandardBlockTwoCodeComparisonsStandard.xml @@ -0,0 +1,31 @@ + + + + + + + class Code {} + ]]> + + + class Comparison {} + ]]> + + + + + $one = 10; + ]]> + + + $a = 10; + ]]> + + + diff --git a/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/TwoStandardBlocksNoCodeStandard.xml b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/TwoStandardBlocksNoCodeStandard.xml new file mode 100644 index 0000000000..f5f621ecdc --- /dev/null +++ b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/TwoStandardBlocksNoCodeStandard.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/TwoStandardBlocksOneCodeComparisonStandard.xml b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/TwoStandardBlocksOneCodeComparisonStandard.xml new file mode 100644 index 0000000000..a5b3a3216e --- /dev/null +++ b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/TwoStandardBlocksOneCodeComparisonStandard.xml @@ -0,0 +1,24 @@ + + + + + + + Code {} + ]]> + + + Comparison {} + ]]> + + + + + + diff --git a/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/TwoStandardBlocksThreeCodeComparisonsStandard.xml b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/TwoStandardBlocksThreeCodeComparisonsStandard.xml new file mode 100644 index 0000000000..540ac7eaf7 --- /dev/null +++ b/tests/Core/Generators/Fixtures/StandardWithDocs/Docs/Structure/TwoStandardBlocksThreeCodeComparisonsStandard.xml @@ -0,0 +1,48 @@ + + + + + + + class Code {} + ]]> + + + class Comparison {} + ]]> + + + + + + + + $one = 10; + ]]> + + + $a = 10; + ]]> + + + + + echo $foo; + ]]> + + + print $foo; + ]]> + + + diff --git a/tests/Core/Generators/Fixtures/StandardWithDocs/Sniffs/DummySniff.php b/tests/Core/Generators/Fixtures/StandardWithDocs/Sniffs/DummySniff.php new file mode 100644 index 0000000000..1a2546b111 --- /dev/null +++ b/tests/Core/Generators/Fixtures/StandardWithDocs/Sniffs/DummySniff.php @@ -0,0 +1,25 @@ + + + + diff --git a/tests/Core/Generators/GeneratorTest.php b/tests/Core/Generators/GeneratorTest.php new file mode 100644 index 0000000000..fd4cdff333 --- /dev/null +++ b/tests/Core/Generators/GeneratorTest.php @@ -0,0 +1,222 @@ + + * @copyright 2024 Juliette Reinders Folmer. All rights reserved. + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Tests\Core\Generators; + +use PHP_CodeSniffer\Ruleset; +use PHP_CodeSniffer\Runner; +use PHP_CodeSniffer\Tests\ConfigDouble; +use PHP_CodeSniffer\Tests\Core\Generators\Fixtures\MockGenerator; +use PHPUnit\Framework\TestCase; + +/** + * Tests the functionality in the abstract Generator class. + * + * @covers \PHP_CodeSniffer\Generators\Generator + */ +final class GeneratorTest extends TestCase +{ + + + /** + * Test the list of available documentation for a standard is generated correctly. + * + * @param string $standard The standard to use for the test. + * @param array $expected The expected list of found docs. + * + * @dataProvider dataConstructor + * + * @return void + */ + public function testConstructor($standard, array $expected) + { + // Set up the ruleset. + $config = new ConfigDouble(["--standard=$standard"]); + $ruleset = new Ruleset($config); + + $generator = new MockGenerator($ruleset); + $this->assertSame($expected, $generator->docFiles); + + }//end testConstructor() + + + /** + * Data provider. + * + * @return array>> + */ + public static function dataConstructor() + { + $pathToDocsInFixture = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'; + $pathToDocsInFixture .= DIRECTORY_SEPARATOR.'StandardWithDocs'; + $pathToDocsInFixture .= DIRECTORY_SEPARATOR.'Docs'.DIRECTORY_SEPARATOR; + + return [ + 'Standard without docs' => [ + 'standard' => __DIR__.'/NoDocsTest.xml', + 'expected' => [], + ], + 'Standard with an invalid doc file' => [ + 'standard' => __DIR__.'/NoValidDocsTest.xml', + 'expected' => [ + $pathToDocsInFixture.'Structure'.DIRECTORY_SEPARATOR.'NoDocumentationElementStandard.xml', + ], + ], + 'Standard with one doc file' => [ + 'standard' => __DIR__.'/OneDocTest.xml', + 'expected' => [ + $pathToDocsInFixture.'Structure'.DIRECTORY_SEPARATOR.'OneStandardBlockNoCodeStandard.xml', + ], + ], + 'Standard with multiple doc files' => [ + 'standard' => __DIR__.'/StructureDocsTest.xml', + 'expected' => [ + $pathToDocsInFixture.'Structure'.DIRECTORY_SEPARATOR.'NoContentStandard.xml', + $pathToDocsInFixture.'Structure'.DIRECTORY_SEPARATOR.'OneStandardBlockCodeComparisonStandard.xml', + $pathToDocsInFixture.'Structure'.DIRECTORY_SEPARATOR.'OneStandardBlockNoCodeStandard.xml', + $pathToDocsInFixture.'Structure'.DIRECTORY_SEPARATOR.'OneStandardBlockTwoCodeComparisonsStandard.xml', + $pathToDocsInFixture.'Structure'.DIRECTORY_SEPARATOR.'TwoStandardBlocksNoCodeStandard.xml', + $pathToDocsInFixture.'Structure'.DIRECTORY_SEPARATOR.'TwoStandardBlocksOneCodeComparisonStandard.xml', + $pathToDocsInFixture.'Structure'.DIRECTORY_SEPARATOR.'TwoStandardBlocksThreeCodeComparisonsStandard.xml', + ], + ], + ]; + + }//end dataConstructor() + + + /** + * Verify that an XML doc which isn't valid documentation yields a TypeError to warn devs. + * + * This should not be hidden via defensive coding! + * + * @return void + */ + public function testGeneratingInvalidDocsResultsInTypeError() + { + // Set up the ruleset. + $standard = __DIR__.'/NoValidDocsTest.xml'; + $config = new ConfigDouble(["--standard=$standard"]); + $ruleset = new Ruleset($config); + + $this->expectException('TypeError'); + $this->expectExceptionMessage('processSniff(): Argument #1 ($doc) must be of type DOMNode, null given'); + + $generator = new MockGenerator($ruleset); + $generator->generate(); + + }//end testGeneratingInvalidDocsResultsInTypeError() + + + /** + * Verify the wiring for the generate() function. + * + * @param string $standard The standard to use for the test. + * @param string $expected The expected function output. + * + * @dataProvider dataGeneratingDocs + * + * @return void + */ + public function testGeneratingDocs($standard, $expected) + { + // Set up the ruleset. + $config = new ConfigDouble(["--standard=$standard"]); + $ruleset = new Ruleset($config); + + // Make the test OS independent. + $expected = str_replace("\n", PHP_EOL, $expected); + $this->expectOutputString($expected); + + $generator = new MockGenerator($ruleset); + $generator->generate(); + + }//end testGeneratingDocs() + + + /** + * Data provider. + * + * @return array> + */ + public static function dataGeneratingDocs() + { + $multidocExpected = "No Content\n"; + $multidocExpected .= "One Standard Block, Code Comparison\n"; + $multidocExpected .= "One Standard Block, No Code\n"; + $multidocExpected .= "One Standard Block, Two Code Comparisons\n"; + $multidocExpected .= "Two Standard Blocks, No Code\n"; + $multidocExpected .= "Two Standard Blocks, One Code Comparison\n"; + $multidocExpected .= "Two Standard Blocks, Three Code Comparisons\n"; + + return [ + 'Standard without docs' => [ + 'standard' => __DIR__.'/NoDocsTest.xml', + 'expected' => '', + ], + 'Standard with one doc file' => [ + 'standard' => __DIR__.'/OneDocTest.xml', + 'expected' => "One Standard Block, No Code\n", + ], + 'Standard with multiple doc files' => [ + 'standard' => __DIR__.'/StructureDocsTest.xml', + 'expected' => $multidocExpected, + ], + ]; + + }//end dataGeneratingDocs() + + + /** + * Test that the documentation for each standard passed on the command-line is shown separately. + * + * @covers \PHP_CodeSniffer\Runner::runPHPCS + * + * @return void + */ + public function testGeneratorWillShowEachStandardSeparately() + { + $standard = __DIR__.'/OneDocTest.xml'; + $_SERVER['argv'] = [ + 'phpcs', + '--generator=Text', + "--standard=$standard,PSR1", + '--report-width=80', + ]; + + $regex = '`^ + \R* # Optional blank line at the start. + (?: + (?P-+\R) # Line with dashes. + \|[ ]GENERATORTEST[ ]CODING[ ]STANDARD:[ ][^\|]+\|\R # Doc title line with prefix expected for first standard. + (?P>delimiter) # Line with dashes. + .+?\R{2} # Standard description. + ) # Only expect this group once. + (?: + (?P>delimiter) # Line with dashes. + \|[ ]PSR1[ ]CODING[ ]STANDARD:[ ][^\|]+\|\R # Doc title line with prefix expected for second standard. + (?P>delimiter) # Line with dashes. + .+?\R+ # Standard description. + (?: + -+[ ]CODE[ ]COMPARISON[ ]-+\R # Code Comparison starter line with dashes. + (?:.+?(?P>delimiter)\R){2} # Arbitrary text followed by a delimiter line. + )* # Code comparison is optional and can exist multiple times. + \R+ + ){3,} # This complete group should occur at least six times. + `sx'; + + $this->expectOutputRegex($regex); + + $runner = new Runner(); + $runner->runPHPCS(); + + }//end testGeneratorWillShowEachStandardSeparately() + + +}//end class diff --git a/tests/Core/Generators/HTMLTest.php b/tests/Core/Generators/HTMLTest.php new file mode 100644 index 0000000000..3106b5029c --- /dev/null +++ b/tests/Core/Generators/HTMLTest.php @@ -0,0 +1,104 @@ + + * @copyright 2024 Juliette Reinders Folmer. All rights reserved. + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Tests\Core\Generators; + +use PHP_CodeSniffer\Ruleset; +use PHP_CodeSniffer\Tests\ConfigDouble; +use PHP_CodeSniffer\Tests\Core\Generators\Fixtures\HTMLDouble; +use PHPUnit\Framework\TestCase; + +/** + * Test the HTML documentation generation. + * + * @covers \PHP_CodeSniffer\Generators\HTML + */ +final class HTMLTest extends TestCase +{ + + + /** + * Test the generated docs. + * + * @param string $standard The standard to use for the test. + * @param string $pathToExpected Path to a file containing the expected function output. + * + * @dataProvider dataDocs + * + * @return void + */ + public function testDocs($standard, $pathToExpected) + { + // Set up the ruleset. + $config = new ConfigDouble(["--standard=$standard"]); + $ruleset = new Ruleset($config); + + $expected = file_get_contents($pathToExpected); + $this->assertNotFalse($expected, 'Output expectation file could not be found'); + + // Make the test OS independent. + $expected = str_replace("\n", PHP_EOL, $expected); + $this->expectOutputString($expected); + + $generator = new HTMLDouble($ruleset); + $generator->generate(); + + }//end testDocs() + + + /** + * Data provider. + * + * @return array> + */ + public static function dataDocs() + { + return [ + 'Standard without docs' => [ + 'standard' => __DIR__.'/NoDocsTest.xml', + 'pathToExpected' => __DIR__.'/Expectations/ExpectedOutputNoDocs.html', + ], + 'Standard with one doc file' => [ + 'standard' => __DIR__.'/OneDocTest.xml', + 'pathToExpected' => __DIR__.'/Expectations/ExpectedOutputOneDoc.html', + ], + 'Standard with multiple doc files' => [ + 'standard' => __DIR__.'/StructureDocsTest.xml', + 'pathToExpected' => __DIR__.'/Expectations/ExpectedOutputStructureDocs.html', + ], + ]; + + }//end dataDocs() + + + /** + * Test the generated footer. + * + * @return void + */ + public function testFooter() + { + // Set up the ruleset. + $standard = __DIR__.'/OneDocTest.xml'; + $config = new ConfigDouble(["--standard=$standard"]); + $ruleset = new Ruleset($config); + + $regex = '`^
'; + $regex .= 'Documentation generated on [A-Z][a-z]{2}, [0-9]{2} [A-Z][a-z]{2} 20[0-9]{2} [0-2][0-9](?::[0-5][0-9]){2} [+-][0-9]{4}'; + $regex .= ' by PHP_CodeSniffer [3-9]\.[0-9]+.[0-9]+'; + $regex .= '
\R \R\R$`'; + $this->expectOutputRegex($regex); + + $generator = new HTMLDouble($ruleset); + $generator->printRealFooter(); + + }//end testFooter() + + +}//end class diff --git a/tests/Core/Generators/MarkdownTest.php b/tests/Core/Generators/MarkdownTest.php new file mode 100644 index 0000000000..a24dae8f69 --- /dev/null +++ b/tests/Core/Generators/MarkdownTest.php @@ -0,0 +1,102 @@ + + * @copyright 2024 Juliette Reinders Folmer. All rights reserved. + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Tests\Core\Generators; + +use PHP_CodeSniffer\Ruleset; +use PHP_CodeSniffer\Tests\ConfigDouble; +use PHP_CodeSniffer\Tests\Core\Generators\Fixtures\MarkdownDouble; +use PHPUnit\Framework\TestCase; + +/** + * Test the Markdown documentation generation. + * + * @covers \PHP_CodeSniffer\Generators\Markdown + */ +final class MarkdownTest extends TestCase +{ + + + /** + * Test the generated docs. + * + * @param string $standard The standard to use for the test. + * @param string $pathToExpected Path to a file containing the expected function output. + * + * @dataProvider dataDocs + * + * @return void + */ + public function testDocs($standard, $pathToExpected) + { + // Set up the ruleset. + $config = new ConfigDouble(["--standard=$standard"]); + $ruleset = new Ruleset($config); + + $expected = file_get_contents($pathToExpected); + $this->assertNotFalse($expected, 'Output expectation file could not be found'); + + // Make the test OS independent. + $expected = str_replace("\n", PHP_EOL, $expected); + $this->expectOutputString($expected); + + $generator = new MarkdownDouble($ruleset); + $generator->generate(); + + }//end testDocs() + + + /** + * Data provider. + * + * @return array> + */ + public static function dataDocs() + { + return [ + 'Standard without docs' => [ + 'standard' => __DIR__.'/NoDocsTest.xml', + 'pathToExpected' => __DIR__.'/Expectations/ExpectedOutputNoDocs.md', + ], + 'Standard with one doc file' => [ + 'standard' => __DIR__.'/OneDocTest.xml', + 'pathToExpected' => __DIR__.'/Expectations/ExpectedOutputOneDoc.md', + ], + 'Standard with multiple doc files' => [ + 'standard' => __DIR__.'/StructureDocsTest.xml', + 'pathToExpected' => __DIR__.'/Expectations/ExpectedOutputStructureDocs.md', + ], + ]; + + }//end dataDocs() + + + /** + * Test the generated footer. + * + * @return void + */ + public function testFooter() + { + // Set up the ruleset. + $standard = __DIR__.'/OneDocTest.xml'; + $config = new ConfigDouble(["--standard=$standard"]); + $ruleset = new Ruleset($config); + + $regex = '`^Documentation generated on [A-Z][a-z]{2}, [0-9]{2} [A-Z][a-z]{2} 20[0-9]{2} [0-2][0-9](?::[0-5][0-9]){2} [+-][0-9]{4}'; + $regex .= ' by \[PHP_CodeSniffer [3-9]\.[0-9]+.[0-9]+\]\(https://github\.com/PHPCSStandards/PHP_CodeSniffer\)\R$`'; + $this->expectOutputRegex($regex); + + $generator = new MarkdownDouble($ruleset); + $generator->printRealFooter(); + + }//end testFooter() + + +}//end class diff --git a/tests/Core/Generators/NoDocsTest.xml b/tests/Core/Generators/NoDocsTest.xml new file mode 100644 index 0000000000..51df8395c0 --- /dev/null +++ b/tests/Core/Generators/NoDocsTest.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/Core/Generators/NoValidDocsTest.xml b/tests/Core/Generators/NoValidDocsTest.xml new file mode 100644 index 0000000000..94dda4e714 --- /dev/null +++ b/tests/Core/Generators/NoValidDocsTest.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/Core/Generators/OneDocTest.xml b/tests/Core/Generators/OneDocTest.xml new file mode 100644 index 0000000000..83ca4384e5 --- /dev/null +++ b/tests/Core/Generators/OneDocTest.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/Core/Generators/StructureDocsTest.xml b/tests/Core/Generators/StructureDocsTest.xml new file mode 100644 index 0000000000..45811bee67 --- /dev/null +++ b/tests/Core/Generators/StructureDocsTest.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/tests/Core/Generators/TextTest.php b/tests/Core/Generators/TextTest.php new file mode 100644 index 0000000000..8961587de0 --- /dev/null +++ b/tests/Core/Generators/TextTest.php @@ -0,0 +1,80 @@ + + * @copyright 2024 Juliette Reinders Folmer. All rights reserved. + * @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + */ + +namespace PHP_CodeSniffer\Tests\Core\Generators; + +use PHP_CodeSniffer\Generators\Text; +use PHP_CodeSniffer\Ruleset; +use PHP_CodeSniffer\Tests\ConfigDouble; +use PHPUnit\Framework\TestCase; + +/** + * Test the Text documentation generation. + * + * @covers \PHP_CodeSniffer\Generators\Text + */ +final class TextTest extends TestCase +{ + + + /** + * Test the generated docs. + * + * @param string $standard The standard to use for the test. + * @param string $pathToExpected Path to a file containing the expected function output. + * + * @dataProvider dataDocs + * + * @return void + */ + public function testDocs($standard, $pathToExpected) + { + // Set up the ruleset. + $config = new ConfigDouble(["--standard=$standard"]); + $ruleset = new Ruleset($config); + + $expected = file_get_contents($pathToExpected); + $this->assertNotFalse($expected, 'Output expectation file could not be found'); + + // Make the test OS independent. + $expected = str_replace("\n", PHP_EOL, $expected); + $this->expectOutputString($expected); + + $generator = new Text($ruleset); + $generator->generate(); + + }//end testDocs() + + + /** + * Data provider. + * + * @return array> + */ + public static function dataDocs() + { + return [ + 'Standard without docs' => [ + 'standard' => __DIR__.'/NoDocsTest.xml', + 'pathToExpected' => __DIR__.'/Expectations/ExpectedOutputEmpty.txt', + ], + 'Standard with one doc file' => [ + 'standard' => __DIR__.'/OneDocTest.xml', + 'pathToExpected' => __DIR__.'/Expectations/ExpectedOutputOneDoc.txt', + ], + 'Standard with multiple doc files' => [ + 'standard' => __DIR__.'/StructureDocsTest.xml', + 'pathToExpected' => __DIR__.'/Expectations/ExpectedOutputStructureDocs.txt', + ], + ]; + + }//end dataDocs() + + +}//end class