Skip to content

Commit

Permalink
Generators: add tests covering handling of invalid docs
Browse files Browse the repository at this point in the history
This adds another set of dedicated tests to safeguard how XML docs which don't follow the specification are handled.

This initial set of tests for this documents the current behaviour [*]. This behaviour may not always be the desired behaviour, in which case, this will be fixed in follow-up commits.

To get these tests up and running, the following fatal errors needed to be fixed:

* Fatal error when a code comparison only contains a single code element:
    ```
    Fatal error: Uncaught Error: Call to a member function getAttribute() on null in path/to/PHP_CodeSniffer/src/Generators/Markdown.php:253
    Stack trace:
    #0 path/to/PHP_CodeSniffer/src/Generators/Markdown.php(139): PHP_CodeSniffer\Generators\Markdown->getFormattedCodeComparisonBlock(Object(DOMElement))
    #1 path/to/PHP_CodeSniffer/src/Generators/Markdown.php(39): PHP_CodeSniffer\Generators\Markdown->processSniff(Object(DOMElement))
    squizlabs#2 path/to/PHP_CodeSniffer/src/Runner.php(99): PHP_CodeSniffer\Generators\Markdown->generate()
    squizlabs#3 path/to/PHP_CodeSniffer/bin/phpcs(14): PHP_CodeSniffer\Runner->runPHPCS()
    squizlabs#4 {main}
      thrown in path/to/PHP_CodeSniffer/src/Generators/Markdown.php on line 253
    ```

* Fatal error when a code element contains no textual content:
    ```
    Fatal error: Uncaught Error: Call to a member function getAttribute() on null in path/to/PHP_CodeSniffer/src/Generators/Markdown.php:246
    Stack trace:
    #0 path/to/PHP_CodeSniffer/src/Generators/Markdown.php(139): PHP_CodeSniffer\Generators\Markdown->getFormattedCodeComparisonBlock(Object(DOMElement))
    #1 path/to/PHP_CodeSniffer/src/Generators/Markdown.php(39): PHP_CodeSniffer\Generators\Markdown->processSniff(Object(DOMElement))
    squizlabs#2 path/to/PHP_CodeSniffer/src/Runner.php(99): PHP_CodeSniffer\Generators\Markdown->generate()
    squizlabs#3 path/to/PHP_CodeSniffer/bin/phpcs(14): PHP_CodeSniffer\Runner->runPHPCS()
    squizlabs#4 {main}
      thrown in path/to/PHP_CodeSniffer/src/Generators/Markdown.php on line 246
    ```

Both of these fatals are fixed by adding defensive coding validating that there are (at least) two code blocks to the `getFormattedCodeComparisonBlock()` methods for all three generator classes.
  • Loading branch information
jrfnl committed Nov 6, 2024
1 parent 6bf83d5 commit 887a35b
Show file tree
Hide file tree
Showing 61 changed files with 1,836 additions and 63 deletions.
17 changes: 12 additions & 5 deletions src/Generators/HTML.php
Original file line number Diff line number Diff line change
Expand Up @@ -383,20 +383,27 @@ protected function printCodeComparisonBlock(DOMNode $node)
*/
protected function getFormattedCodeComparisonBlock(DOMNode $node)
{
$codeBlocks = $node->getElementsByTagName('code');
$codeBlocks = $node->getElementsByTagName('code');
$firstCodeElm = $codeBlocks->item(0);
$secondCodeElm = $codeBlocks->item(1);

$firstTitle = trim($codeBlocks->item(0)->getAttribute('title'));
if (isset($firstCodeElm, $secondCodeElm) === false) {
// Missing at least one code block.
return '';
}

$firstTitle = trim($firstCodeElm->getAttribute('title'));
$firstTitle = str_replace(' ', '  ', $firstTitle);
$first = trim($codeBlocks->item(0)->nodeValue);
$first = trim($firstCodeElm->nodeValue);
$first = str_replace('<?php', '&lt;?php', $first);
$first = str_replace("\n", '</br>', $first);
$first = str_replace(' ', '&nbsp;', $first);
$first = str_replace('<em>', '<span class="code-comparison-highlight">', $first);
$first = str_replace('</em>', '</span>', $first);

$secondTitle = trim($codeBlocks->item(1)->getAttribute('title'));
$secondTitle = trim($secondCodeElm->getAttribute('title'));
$secondTitle = str_replace(' ', '&nbsp;&nbsp;', $secondTitle);
$second = trim($codeBlocks->item(1)->nodeValue);
$second = trim($secondCodeElm->nodeValue);
$second = str_replace('<?php', '&lt;?php', $second);
$second = str_replace("\n", '</br>', $second);
$second = str_replace(' ', '&nbsp;', $second);
Expand Down
17 changes: 12 additions & 5 deletions src/Generators/Markdown.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,18 +241,25 @@ protected function printCodeComparisonBlock(DOMNode $node)
*/
protected function getFormattedCodeComparisonBlock(DOMNode $node)
{
$codeBlocks = $node->getElementsByTagName('code');
$codeBlocks = $node->getElementsByTagName('code');
$firstCodeElm = $codeBlocks->item(0);
$secondCodeElm = $codeBlocks->item(1);

$firstTitle = trim($codeBlocks->item(0)->getAttribute('title'));
if (isset($firstCodeElm, $secondCodeElm) === false) {
// Missing at least one code block.
return '';
}

$firstTitle = trim($firstCodeElm->getAttribute('title'));
$firstTitle = str_replace(' ', '&nbsp;&nbsp;', $firstTitle);
$first = trim($codeBlocks->item(0)->nodeValue);
$first = trim($firstCodeElm->nodeValue);
$first = str_replace("\n", PHP_EOL.' ', $first);
$first = str_replace('<em>', '', $first);
$first = str_replace('</em>', '', $first);

$secondTitle = trim($codeBlocks->item(1)->getAttribute('title'));
$secondTitle = trim($secondCodeElm->getAttribute('title'));
$secondTitle = str_replace(' ', '&nbsp;&nbsp;', $secondTitle);
$second = trim($codeBlocks->item(1)->nodeValue);
$second = trim($secondCodeElm->nodeValue);
$second = str_replace("\n", PHP_EOL.' ', $second);
$second = str_replace('<em>', '', $second);
$second = str_replace('</em>', '', $second);
Expand Down
18 changes: 13 additions & 5 deletions src/Generators/Text.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,17 @@ protected function printCodeComparisonBlock(DOMNode $node)
*/
protected function getFormattedCodeComparisonBlock(DOMNode $node)
{
$codeBlocks = $node->getElementsByTagName('code');
$first = trim($codeBlocks->item(0)->nodeValue);
$firstTitle = trim($codeBlocks->item(0)->getAttribute('title'));
$codeBlocks = $node->getElementsByTagName('code');
$firstCodeElm = $codeBlocks->item(0);
$secondCodeElm = $codeBlocks->item(1);

if (isset($firstCodeElm, $secondCodeElm) === false) {
// Missing at least one code block.
return '';
}

$first = trim($firstCodeElm->nodeValue);
$firstTitle = trim($firstCodeElm->getAttribute('title'));

$firstTitleLines = [];
$tempTitle = '';
Expand Down Expand Up @@ -234,8 +242,8 @@ protected function getFormattedCodeComparisonBlock(DOMNode $node)
$first = str_replace('</em>', '', $first);
$firstLines = explode("\n", $first);

$second = trim($codeBlocks->item(1)->nodeValue);
$secondTitle = trim($codeBlocks->item(1)->getAttribute('title'));
$second = trim($secondCodeElm->nodeValue);
$secondTitle = trim($secondCodeElm->getAttribute('title'));

$secondTitleLines = [];
$tempTitle = '';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<html>
<head>
<title>GeneratorTest Coding Standards</title>
<style>
body {
background-color: #FFFFFF;
font-size: 14px;
font-family: Arial, Helvetica, sans-serif;
color: #000000;
}

h1 {
color: #666666;
font-size: 20px;
font-weight: bold;
margin-top: 0px;
background-color: #E6E7E8;
padding: 20px;
border: 1px solid #BBBBBB;
}

h2 {
color: #00A5E3;
font-size: 16px;
font-weight: normal;
margin-top: 50px;
}

.code-comparison {
width: 100%;
}

.code-comparison td {
border: 1px solid #CCCCCC;
}

.code-comparison-title, .code-comparison-code {
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
color: #000000;
vertical-align: top;
padding: 4px;
width: 50%;
background-color: #F1F1F1;
line-height: 15px;
}

.code-comparison-code {
font-family: Courier;
background-color: #F9F9F9;
}

.code-comparison-highlight {
background-color: #DDF1F7;
border: 1px solid #00A5E3;
line-height: 15px;
}

.tag-line {
text-align: center;
width: 100%;
margin-top: 30px;
font-size: 12px;
}

.tag-line a {
color: #000000;
}
</style>
</head>
<body>
<h1>GeneratorTest Coding Standards</h1>
<a name="Code-Comparison,-mismatched-code-blocks" />
<h2>Code Comparison, mismatched code blocks</h2>
<p class="text">This doc has two code elements, one only has a title, one has actual code. Unbalanced</p>
<table class="code-comparison">
<tr>
<td class="code-comparison-title">Code title</td>
<td class="code-comparison-title"></td>
</tr>
<tr>
<td class="code-comparison-code"></td>
<td class="code-comparison-code">$a&nbsp;=&nbsp;'Example&nbsp;code';</td>
</tr>
</table>
<div class="tag-line">Documentation generated on #REDACTED# by <a href="https://github.com/PHPCSStandards/PHP_CodeSniffer">PHP_CodeSniffer #VERSION#</a></div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# GeneratorTest Coding Standard

## Code Comparison, mismatched code blocks

This doc has two code elements, one only has a title, one has actual code. Unbalanced
<table>
<tr>
<th>Code title</th>
<th></th>
</tr>
<tr>
<td>



</td>
<td>

$a = 'Example code';

</td>
</tr>
</table>

Documentation generated on *REDACTED* by [PHP_CodeSniffer *VERSION*](https://github.com/PHPCSStandards/PHP_CodeSniffer)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

--------------------------------------------------------------------------
| GENERATORTEST CODING STANDARD: CODE COMPARISON, MISMATCHED CODE BLOCKS |
--------------------------------------------------------------------------

This doc has two code elements, one only has a title, one has actual code. Unbalanced

----------------------------------------- CODE COMPARISON ------------------------------------------
| Code title | |
----------------------------------------------------------------------------------------------------
| | $a = 'Example code'; |
----------------------------------------------------------------------------------------------------

Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<html>
<head>
<title>GeneratorTest Coding Standards</title>
<style>
body {
background-color: #FFFFFF;
font-size: 14px;
font-family: Arial, Helvetica, sans-serif;
color: #000000;
}

h1 {
color: #666666;
font-size: 20px;
font-weight: bold;
margin-top: 0px;
background-color: #E6E7E8;
padding: 20px;
border: 1px solid #BBBBBB;
}

h2 {
color: #00A5E3;
font-size: 16px;
font-weight: normal;
margin-top: 50px;
}

.code-comparison {
width: 100%;
}

.code-comparison td {
border: 1px solid #CCCCCC;
}

.code-comparison-title, .code-comparison-code {
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
color: #000000;
vertical-align: top;
padding: 4px;
width: 50%;
background-color: #F1F1F1;
line-height: 15px;
}

.code-comparison-code {
font-family: Courier;
background-color: #F9F9F9;
}

.code-comparison-highlight {
background-color: #DDF1F7;
border: 1px solid #00A5E3;
line-height: 15px;
}

.tag-line {
text-align: center;
width: 100%;
margin-top: 30px;
font-size: 12px;
}

.tag-line a {
color: #000000;
}
</style>
</head>
<body>
<h1>GeneratorTest Coding Standards</h1>
<a name="Code-Comparison,-missing-code-element" />
<h2>Code Comparison, missing code element</h2>
<p class="text">This is a standard block.</p>
<div class="tag-line">Documentation generated on #REDACTED# by <a href="https://github.com/PHPCSStandards/PHP_CodeSniffer">PHP_CodeSniffer #VERSION#</a></div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# GeneratorTest Coding Standard

## Code Comparison, missing code element

This is a standard block.

Documentation generated on *REDACTED* by [PHP_CodeSniffer *VERSION*](https://github.com/PHPCSStandards/PHP_CodeSniffer)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

------------------------------------------------------------------------
| GENERATORTEST CODING STANDARD: CODE COMPARISON, MISSING CODE ELEMENT |
------------------------------------------------------------------------

This is a standard block.

Loading

0 comments on commit 887a35b

Please sign in to comment.