44
55namespace Phauthentic \CognitiveCodeAnalysis \Business \Churn \Exporter ;
66
7+ use Phauthentic \CognitiveCodeAnalysis \Business \Exporter \MarkdownFormatterTrait ;
8+ use Phauthentic \CognitiveCodeAnalysis \Business \Traits \CoverageDataDetector ;
79use Phauthentic \CognitiveCodeAnalysis \Business \Utility \Datetime ;
810use Phauthentic \CognitiveCodeAnalysis \CognitiveAnalysisException ;
911
1012/**
1113 * MarkdownExporter for Churn metrics.
1214 */
13- class MarkdownExporter implements DataExporterInterface
15+ class MarkdownExporter extends AbstractExporter
1416{
17+ use MarkdownFormatterTrait;
18+ use CoverageDataDetector;
19+
1520 /**
1621 * @var array<string>
1722 */
@@ -42,11 +47,11 @@ class MarkdownExporter implements DataExporterInterface
4247 */
4348 public function export (array $ classes , string $ filename ): void
4449 {
50+ $ this ->assertFileIsWritable ($ filename );
51+
4552 $ markdown = $ this ->generateMarkdown ($ classes );
4653
47- if (file_put_contents ($ filename , $ markdown ) === false ) {
48- throw new CognitiveAnalysisException ("Unable to write to file: $ filename " );
49- }
54+ $ this ->writeFile ($ filename , $ markdown );
5055 }
5156
5257 /**
@@ -63,64 +68,48 @@ private function generateMarkdown(array $classes): string
6368 $ markdown .= "Total Classes: " . count ($ classes ) . "\n\n" ;
6469
6570 // Create table header
66- $ markdown .= " | " . implode ( " | " , $ header ) . " | \n" ;
67- $ markdown .= " | " . str_repeat ( " --- | " , count ($ header )) . "\n" ;
71+ $ markdown .= $ this -> buildMarkdownTableHeader ( $ header ) . "\n" ;
72+ $ markdown .= $ this -> buildMarkdownTableSeparator ( count ($ header )) . "\n" ;
6873
6974 // Add rows
7075 foreach ($ classes as $ className => $ data ) {
7176 if ($ data ['score ' ] == 0 || $ data ['churn ' ] == 0 ) {
7277 continue ;
7378 }
7479
75- $ row = [
76- $ this ->escapeMarkdown ($ className ),
77- (string )$ data ['score ' ],
78- (string )round ($ data ['churn ' ], 3 ),
79- ];
80-
81- if ($ hasCoverageData ) {
82- $ row [] = $ data ['riskChurn ' ] !== null ? (string )round ($ data ['riskChurn ' ], 3 ) : 'N/A ' ;
83- }
84-
85- $ row [] = (string )$ data ['timesChanged ' ];
86-
87- if ($ hasCoverageData ) {
88- $ row [] = $ data ['coverage ' ] !== null ? sprintf ('%.2f%% ' , $ data ['coverage ' ] * 100 ) : 'N/A ' ;
89- $ row [] = $ data ['riskLevel ' ] ?? 'N/A ' ;
90- }
91-
92- $ markdown .= "| " . implode (" | " , $ row ) . " | \n" ;
80+ $ markdown .= $ this ->addRow ($ className , $ data , $ hasCoverageData );
9381 }
9482
9583 return $ markdown ;
9684 }
9785
9886 /**
99- * Check if any class has coverage data
87+ * Add a single row to the markdown table
10088 *
101- * @param array<string, mixed> $classes
102- * @return bool
89+ * @param string $className
90+ * @param array<string, mixed> $data
91+ * @param bool $hasCoverageData
92+ * @return string
10393 */
104- private function hasCoverageData ( array $ classes ): bool
94+ private function addRow ( string $ className , array $ data , bool $ hasCoverageData ): string
10595 {
106- foreach ($ classes as $ data ) {
107- if (array_key_exists ('coverage ' , $ data ) && $ data ['coverage ' ] !== null ) {
108- return true ;
109- }
96+ $ row = [
97+ $ this ->escapeMarkdown ($ className ),
98+ (string )$ data ['score ' ],
99+ (string )round ((float )$ data ['churn ' ], 3 ),
100+ ];
101+
102+ if ($ hasCoverageData ) {
103+ $ row [] = $ data ['riskChurn ' ] !== null ? (string )round ((float )$ data ['riskChurn ' ], 3 ) : 'N/A ' ;
110104 }
111105
112- return false ;
113- }
106+ $ row [] = (string )$ data ['timesChanged ' ];
114107
115- /**
116- * Escape special markdown characters in strings
117- *
118- * @param string $string
119- * @return string
120- */
121- private function escapeMarkdown (string $ string ): string
122- {
123- // Escape pipe characters which would break table formatting
124- return str_replace ('| ' , '\\| ' , $ string );
108+ if ($ hasCoverageData ) {
109+ $ row [] = $ data ['coverage ' ] !== null ? sprintf ('%.2f%% ' , $ data ['coverage ' ] * 100 ) : 'N/A ' ;
110+ $ row [] = $ data ['riskLevel ' ] ?? 'N/A ' ;
111+ }
112+
113+ return "| " . implode (" | " , $ row ) . " | \n" ;
125114 }
126115}
0 commit comments