All files / src/utils report.ts

100% Statements 99/99
95.83% Branches 23/24
100% Functions 3/3
100% Lines 99/99

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 1002x 2x 2x 7x 7x 7x 7x 7x 7x 7x 7x 2x 7x 7x 7x 2x 7x 7x 7x 7x 7x 7x 7x 7x 7x 6x 6x 7x 1x 1x 1x 7x 1x 1x 1x 1x 1x 1x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 1x 1x 1x 4x 4x 4x 1x 1x 4x 1x 1x 7x 7x 1x 1x 1x 1x 1x 1x 1x 1x 7x 7x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 1x 1x 7x 7x 4x 4x 4x 7x 7x 7x  
import { MergedReport } from '../merger/merger';
import { t } from '../i18n/messages';
 
function severityEmoji(severity: string): string {
  switch (severity) {
    case 'error': return '🔴';
    case 'warning': return '🟡';
    case 'info': return '🔵';
    default: return '⚪';
  }
}
 
function formatLine(line: number): string {
  return Number.isFinite(line) ? `L${line + 1}` : 'L?';
}
 
export function reportToMarkdown(report: MergedReport): string {
  const lines: string[] = [];
 
  lines.push(`# ${t('report.title')}`);
  lines.push('');
  lines.push(`**${t('report.file')}:** \`${report.filePath}\``);
  lines.push(`**${t('report.language')}:** ${report.language}`);
  lines.push(`**${t('report.duration')}:** ${(report.duration / 1000).toFixed(1)}s`);
  if (report.adapterNames.length > 0) {
    lines.push(`**${t('report.tools')}:** ${report.adapterNames.join(', ')}`);
  }
  if (report.degraded) {
    lines.push('');
    lines.push(`> ⚠️ ${t('report.degradedBanner')}`);
  }
  if (report.errors.length > 0) {
    lines.push('');
    lines.push(`## ${t('report.errors')}`);
    for (const err of report.errors) {
      lines.push(`- ${err}`);
    }
  }
 
  lines.push('');
  lines.push('---');
  lines.push('');
 
  const total = report.linterCount + report.customRuleCount + report.aiCount;
  const errors = report.linterDiagnostics.filter(d => d.severity === 'error').length
    + report.customRuleDiagnostics.filter(d => d.severity === 'error').length
    + report.aiFindings.filter(f => f.severity === 'error').length;
  const warnings = report.linterDiagnostics.filter(d => d.severity === 'warning').length
    + report.customRuleDiagnostics.filter(d => d.severity === 'warning').length
    + report.aiFindings.filter(f => f.severity === 'warning').length;
  const infos = total - errors - warnings;
 
  lines.push(t('report.totalSummary', { 0: String(total), 1: String(errors), 2: String(warnings), 3: String(infos) }));
  lines.push('');
 
  if (report.linterDiagnostics.length > 0) {
    lines.push(t('report.staticSection', { 0: String(report.linterCount) }));
    lines.push('');
    for (const diag of report.linterDiagnostics) {
      lines.push(`- ${severityEmoji(diag.severity)} \`${diag.ruleId}\` ${formatLine(diag.range.start.line)}`);
      lines.push(`  ${diag.message}`);
      if (diag.suggestion) {
        lines.push(`  ${t('report.suggestion')}: ${diag.suggestion}`);
      }
    }
    lines.push('');
  }
 
  if (report.customRuleDiagnostics.length > 0) {
    lines.push(t('report.customSection', { 0: String(report.customRuleCount) }));
    lines.push('');
    for (const diag of report.customRuleDiagnostics) {
      lines.push(`- ${severityEmoji(diag.severity)} \`${diag.ruleId}\` ${formatLine(diag.range.start.line)}`);
      lines.push(`  ${diag.message}`);
    }
    lines.push('');
  }
 
  if (report.aiFindings.length > 0) {
    lines.push(t('report.aiSection', { 0: String(report.aiCount) }));
    lines.push('');
    for (const finding of report.aiFindings) {
      lines.push(`- ${severityEmoji(finding.severity)} [AI] [${finding.category}] \`${finding.ruleId}\` ${formatLine(finding.line)}`);
      lines.push(`  **${finding.title}**`);
      lines.push(`  ${finding.description}`);
      if (finding.suggestion) {
        lines.push(`  ${t('report.suggestion')}: ${finding.suggestion}`);
      }
    }
    lines.push('');
  }
 
  if (total === 0) {
    lines.push(`✅ ${t('report.noProblems')}`);
    lines.push('');
  }
 
  return lines.join('\n');
}