Skip to content

Commit 6ebb1dd

Browse files
committed
Generators/Markdown: don't print title if there is no content
This refactors the class to _retrieve_ the intended output, instead of echo-ing it out directly and validates whether it makes sense to print anything at all about a sniff before sending the output to screen. It deprecates the following methods, which will be removed in PHPCS 4.0: * `printHeader()` in favour of `getFormattedHeader()` * `printFooter()` in favour of `getFormattedFooter()` * `printTextBlock()` in favour of `getFormattedTextBlock()` * `printCodeComparisonBlock()` in favour of `getFormattedCodeComparisonBlock()`
1 parent b270e99 commit 6ebb1dd

File tree

6 files changed

+140
-68
lines changed

6 files changed

+140
-68
lines changed

src/Generators/Markdown.php

Lines changed: 117 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,53 +32,92 @@ public function generate()
3232
}
3333

3434
ob_start();
35-
$this->printHeader();
36-
3735
foreach ($this->docFiles as $file) {
3836
$doc = new DOMDocument();
3937
$doc->load($file);
4038
$documentation = $doc->getElementsByTagName('documentation')->item(0);
4139
$this->processSniff($documentation);
4240
}
4341

44-
$this->printFooter();
4542
$content = ob_get_contents();
4643
ob_end_clean();
4744

48-
echo $content;
45+
if (trim($content) !== '') {
46+
echo $this->getFormattedHeader();
47+
echo $content;
48+
echo $this->getFormattedFooter();
49+
}
4950

5051
}//end generate()
5152

5253

5354
/**
5455
* Print the markdown header.
5556
*
57+
* @deprecated 3.12.0 Use Markdown::getFormattedHeader() instead.
58+
*
59+
* @codeCoverageIgnore
60+
*
5661
* @return void
5762
*/
5863
protected function printHeader()
64+
{
65+
echo $this->getFormattedHeader();
66+
67+
}//end printHeader()
68+
69+
70+
/**
71+
* Format the markdown header.
72+
*
73+
* @since 3.12.0 Replaces the deprecated Markdown::printHeader() method.
74+
*
75+
* @return string
76+
*/
77+
protected function getFormattedHeader()
5978
{
6079
$standard = $this->ruleset->name;
6180

62-
echo "# $standard Coding Standard".PHP_EOL;
81+
return "# $standard Coding Standard".PHP_EOL;
6382

64-
}//end printHeader()
83+
}//end getFormattedHeader()
6584

6685

6786
/**
6887
* Print the markdown footer.
6988
*
89+
* @deprecated 3.12.0 Use Markdown::getFormattedFooter() instead.
90+
*
91+
* @codeCoverageIgnore
92+
*
7093
* @return void
7194
*/
7295
protected function printFooter()
96+
{
97+
echo $this->getFormattedFooter();
98+
99+
}//end printFooter()
100+
101+
102+
/**
103+
* Format the markdown footer.
104+
*
105+
* @since 3.12.0 Replaces the deprecated Markdown::printFooter() method.
106+
*
107+
* @return string
108+
*/
109+
protected function getFormattedFooter()
73110
{
74111
// Turn off errors so we don't get timezone warnings if people
75112
// don't have their timezone set.
76113
$errorLevel = error_reporting(0);
77-
echo PHP_EOL.'Documentation generated on '.date('r');
78-
echo ' by [PHP_CodeSniffer '.Config::VERSION.'](https://github.com/PHPCSStandards/PHP_CodeSniffer)'.PHP_EOL;
114+
$output = PHP_EOL.'Documentation generated on '.date('r');
115+
$output .= ' by [PHP_CodeSniffer '.Config::VERSION.'](https://github.com/PHPCSStandards/PHP_CodeSniffer)'.PHP_EOL;
79116
error_reporting($errorLevel);
80117

81-
}//end printFooter()
118+
return $output;
119+
120+
}//end getFormattedFooter()
82121

83122

84123
/**
@@ -92,17 +131,21 @@ protected function printFooter()
92131
*/
93132
protected function processSniff(DOMNode $doc)
94133
{
95-
$title = $this->getTitle($doc);
96-
echo PHP_EOL."## $title".PHP_EOL.PHP_EOL;
97-
134+
$content = '';
98135
foreach ($doc->childNodes as $node) {
99136
if ($node->nodeName === 'standard') {
100-
$this->printTextBlock($node);
137+
$content .= $this->getFormattedTextBlock($node);
101138
} else if ($node->nodeName === 'code_comparison') {
102-
$this->printCodeComparisonBlock($node);
139+
$content .= $this->getFormattedCodeComparisonBlock($node);
103140
}
104141
}
105142

143+
if (trim($content) !== '') {
144+
$title = $this->getTitle($doc);
145+
echo PHP_EOL."## $title".PHP_EOL.PHP_EOL;
146+
echo $content;
147+
}
148+
106149
}//end processSniff()
107150

108151

@@ -111,9 +154,29 @@ protected function processSniff(DOMNode $doc)
111154
*
112155
* @param \DOMNode $node The DOMNode object for the text block.
113156
*
157+
* @deprecated 3.12.0 Use Markdown::getFormattedTextBlock() instead.
158+
*
159+
* @codeCoverageIgnore
160+
*
114161
* @return void
115162
*/
116163
protected function printTextBlock(DOMNode $node)
164+
{
165+
echo $this->getFormattedTextBlock($node);
166+
167+
}//end printTextBlock()
168+
169+
170+
/**
171+
* Format a text block found in a standard.
172+
*
173+
* @param \DOMNode $node The DOMNode object for the text block.
174+
*
175+
* @since 3.12.0 Replaces the deprecated Markdown::printTextBlock() method.
176+
*
177+
* @return string
178+
*/
179+
protected function getFormattedTextBlock(DOMNode $node)
117180
{
118181
$content = trim($node->nodeValue);
119182
$content = htmlspecialchars($content, (ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401));
@@ -144,19 +207,39 @@ protected function printTextBlock(DOMNode $node)
144207
}
145208
}
146209

147-
echo implode(PHP_EOL, $lines).PHP_EOL;
210+
return implode(PHP_EOL, $lines).PHP_EOL;
148211

149-
}//end printTextBlock()
212+
}//end getFormattedTextBlock()
150213

151214

152215
/**
153216
* Print a code comparison block found in a standard.
154217
*
155218
* @param \DOMNode $node The DOMNode object for the code comparison block.
156219
*
220+
* @deprecated 3.12.0 Use Markdown::getFormattedCodeComparisonBlock() instead.
221+
*
222+
* @codeCoverageIgnore
223+
*
157224
* @return void
158225
*/
159226
protected function printCodeComparisonBlock(DOMNode $node)
227+
{
228+
echo $this->getFormattedCodeComparisonBlock($node);
229+
230+
}//end printCodeComparisonBlock()
231+
232+
233+
/**
234+
* Format a code comparison block found in a standard.
235+
*
236+
* @param \DOMNode $node The DOMNode object for the code comparison block.
237+
*
238+
* @since 3.12.0 Replaces the deprecated Markdown::printCodeComparisonBlock() method.
239+
*
240+
* @return string
241+
*/
242+
protected function getFormattedCodeComparisonBlock(DOMNode $node)
160243
{
161244
$codeBlocks = $node->getElementsByTagName('code');
162245

@@ -174,22 +257,24 @@ protected function printCodeComparisonBlock(DOMNode $node)
174257
$second = str_replace('<em>', '', $second);
175258
$second = str_replace('</em>', '', $second);
176259

177-
echo ' <table>'.PHP_EOL;
178-
echo ' <tr>'.PHP_EOL;
179-
echo " <th>$firstTitle</th>".PHP_EOL;
180-
echo " <th>$secondTitle</th>".PHP_EOL;
181-
echo ' </tr>'.PHP_EOL;
182-
echo ' <tr>'.PHP_EOL;
183-
echo '<td>'.PHP_EOL.PHP_EOL;
184-
echo " $first".PHP_EOL.PHP_EOL;
185-
echo '</td>'.PHP_EOL;
186-
echo '<td>'.PHP_EOL.PHP_EOL;
187-
echo " $second".PHP_EOL.PHP_EOL;
188-
echo '</td>'.PHP_EOL;
189-
echo ' </tr>'.PHP_EOL;
190-
echo ' </table>'.PHP_EOL;
191-
192-
}//end printCodeComparisonBlock()
260+
$output = ' <table>'.PHP_EOL;
261+
$output .= ' <tr>'.PHP_EOL;
262+
$output .= " <th>$firstTitle</th>".PHP_EOL;
263+
$output .= " <th>$secondTitle</th>".PHP_EOL;
264+
$output .= ' </tr>'.PHP_EOL;
265+
$output .= ' <tr>'.PHP_EOL;
266+
$output .= '<td>'.PHP_EOL.PHP_EOL;
267+
$output .= " $first".PHP_EOL.PHP_EOL;
268+
$output .= '</td>'.PHP_EOL;
269+
$output .= '<td>'.PHP_EOL.PHP_EOL;
270+
$output .= " $second".PHP_EOL.PHP_EOL;
271+
$output .= '</td>'.PHP_EOL;
272+
$output .= ' </tr>'.PHP_EOL;
273+
$output .= ' </table>'.PHP_EOL;
274+
275+
return $output;
276+
277+
}//end getFormattedCodeComparisonBlock()
193278

194279

195280
}//end class

tests/Core/Generators/Expectations/ExpectedOutputStructureDocs.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
# GeneratorTest Coding Standard
22

3-
## No Content
4-
5-
63
## Code Comparison Only, Missing Standard Block
74

85
<table>

tests/Core/Generators/Expectations/ExpectedOutputUnsupportedElementAtWrongLevel.md

Lines changed: 0 additions & 6 deletions
This file was deleted.

tests/Core/Generators/Expectations/ExpectedOutputUnsupportedUnknownElement.md

Lines changed: 0 additions & 6 deletions
This file was deleted.

tests/Core/Generators/Fixtures/MarkdownDouble.php

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,25 @@ class MarkdownDouble extends Markdown
1414
{
1515

1616
/**
17-
* Print the markdown footer without the date or version nr to make the expectation fixtures stable.
17+
* Format the markdown footer without the date or version nr to make the expectation fixtures stable.
1818
*
19-
* @return void
19+
* @return string
2020
*/
21-
protected function printFooter()
21+
protected function getFormattedFooter()
2222
{
23-
echo PHP_EOL.'Documentation generated on *REDACTED*';
24-
echo ' by [PHP_CodeSniffer *VERSION*](https://github.com/PHPCSStandards/PHP_CodeSniffer)'.PHP_EOL;
23+
$output = PHP_EOL.'Documentation generated on *REDACTED*';
24+
$output .= ' by [PHP_CodeSniffer *VERSION*](https://github.com/PHPCSStandards/PHP_CodeSniffer)'.PHP_EOL;
25+
26+
return $output;
2527
}
2628

2729
/**
28-
* Print the _real_ footer of the markdown page.
30+
* Retrieve the _real_ footer of the markdown page.
2931
*
30-
* @return void
32+
* @return string
3133
*/
32-
public function printRealFooter()
34+
public function getRealFooter()
3335
{
34-
parent::printFooter();
36+
return parent::getFormattedFooter();
3537
}
3638
}

tests/Core/Generators/MarkdownTest.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public static function dataDocSpecifics()
175175
],
176176
'Unsupported: <code> element at the wrong level' => [
177177
'sniffs' => 'StandardWithDocs.Unsupported.ElementAtWrongLevel',
178-
'pathToExpected' => __DIR__.'/Expectations/ExpectedOutputUnsupportedElementAtWrongLevel.md',
178+
'pathToExpected' => __DIR__.'/Expectations/ExpectedOutputEmpty.txt',
179179
],
180180
'Unsupported: one correct elm, one at wrong level' => [
181181
'sniffs' => 'StandardWithDocs.Unsupported.OneElmAtWrongLevel',
@@ -187,7 +187,7 @@ public static function dataDocSpecifics()
187187
],
188188
'Unsupported: unknown element' => [
189189
'sniffs' => 'StandardWithDocs.Unsupported.UnknownElement',
190-
'pathToExpected' => __DIR__.'/Expectations/ExpectedOutputUnsupportedUnknownElement.md',
190+
'pathToExpected' => __DIR__.'/Expectations/ExpectedOutputEmpty.txt',
191191
],
192192
];
193193

@@ -208,10 +208,16 @@ public function testFooter()
208208

209209
$regex = '`^\RDocumentation 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}';
210210
$regex .= ' by \[PHP_CodeSniffer [3-9]\.[0-9]+.[0-9]+\]\(https://github\.com/PHPCSStandards/PHP_CodeSniffer\)\R$`';
211-
$this->expectOutputRegex($regex);
212211

213212
$generator = new MarkdownDouble($ruleset);
214-
$generator->printRealFooter();
213+
$footer = $generator->getRealFooter();
214+
215+
if (method_exists($this, 'assertMatchesRegularExpression') === true) {
216+
$this->assertMatchesRegularExpression($regex, $footer);
217+
} else {
218+
// PHPUnit < 9.1.0.
219+
$this->assertRegExp($regex, $footer);
220+
}
215221

216222
}//end testFooter()
217223

@@ -233,11 +239,8 @@ public function testFooterResetsErrorReportingToOriginalSetting()
233239
$config = new ConfigDouble(["--standard=$standard"]);
234240
$ruleset = new Ruleset($config);
235241

236-
// We know there will be output, but we're not interested in the output for this test.
237-
ob_start();
238242
$generator = new MarkdownDouble($ruleset);
239-
$generator->printRealFooter();
240-
ob_end_clean();
243+
$generator->getRealFooter();
241244

242245
$this->assertSame($expected, error_reporting());
243246

@@ -275,11 +278,8 @@ public function testFooterDoesntThrowWarningOnMissingTimezone()
275278
$config = new ConfigDouble(["--standard=$standard"]);
276279
$ruleset = new Ruleset($config);
277280

278-
// We know there will be output, but we're not interested in the output for this test.
279-
ob_start();
280281
$generator = new MarkdownDouble($ruleset);
281-
$generator->printRealFooter();
282-
ob_end_clean();
282+
$generator->getRealFooter();
283283

284284
// Reset the timezone to its original state.
285285
ini_set('date.timezone', $originalIni);

0 commit comments

Comments
 (0)