From 109d1365e119ae1347fa89f0dbcaf676c457bdec Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 3 Nov 2024 14:21:17 +0100 Subject: [PATCH] Generators: add initial set of tests These new tests safeguard the output generated by the `Text`, `Markdown` and `HTML` doc generators and the logic in the abstract `Generator` class. **Notes about the setup for these tests**: These tests use a set of test fixtures specially crafted for these tests. The use of fixtures means that the tests don't use _real_ documentation as included with the various standards, which is subject to change and would make the tests unstable. As the test fixtures are set up as an external standard, these tests will not only safeguard that doc generation works as expected, but also that it continues to work with external standards. This should help prevent issues as previously fixed in a10bea65d6cecc20e9599fc8b0b5d1e786b534f6 and e5bdaad2616a89d5c4ad1fdae9491dd96b59bb3a. The footer output for the `Markdown` and `HTML` generators contains a date and a PHPCS version nr, which, again, would make the tests unstable. To mitigate this, test double classes are included for these classes, which overload the `printFooter()` methods and replaces the date and PHPCS version number with placeholders for the generic documentation tests. The _real_ footer is still tested, but via a regex pattern in a separate test in the `MarkdownTest` and `HTMLTest` classes. Finally, as things were, the tests for `Markdown` and `HTML` would fail on Windows due to the generated output containing mixed line endings in the HTML ` + + +

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