๐ reporter.ts โข 4690 bytes
/**
* ้ช่ฏ็ณป็ป - ๆฅๅ็ๆ
* Phase 3: ้ช่ฏๆฅๅ
*/
import {
type VerificationReport,
type VerificationResult,
type VerificationIssue,
type VerificationOptions
} from './types'
import { STATUS_LABELS, TYPE_LABELS } from './types'
/** ็ๆๅฏไธID */
function generateId(): string {
return 'vr_' + Date.now().toString(36) + '_' + Math.random().toString(36).slice(2, 6)
}
/**
* ๅๅปบ้ช่ฏๆฅๅ
*/
export function createReport(file: string): VerificationReport {
return {
id: generateId(),
file,
timestamp: new Date().toISOString(),
results: [],
overallPassed: true,
summary: {
total: 0,
passed: 0,
failed: 0,
warnings: 0,
},
}
}
/**
* ๆทปๅ ้ช่ฏ็ปๆๅฐๆฅๅ
*/
export function addResult(
report: VerificationReport,
result: VerificationResult
): void {
report.results.push(result)
// ๆดๆฐๆ่ฆ
report.summary.total++
if (result.passed) {
report.summary.passed++
} else {
report.summary.failed++
}
report.summary.warnings += result.issues.filter(i => i.type === 'warning').length
// ๆดๆฐๆดไฝ็ถๆ
if (!result.passed) {
report.overallPassed = false
}
}
/**
* ๆ ผๅผๅ้ช่ฏๆฅๅไธบๆๆฌ
*/
export function formatReport(report: VerificationReport): string {
let output = '\n'
output += ' โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n'
output += ` โ ๐ ้ช่ฏๆฅๅ: ${report.file.padEnd(30)}โ\n`
output += ' โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n\n'
output += ` ๐ ๆไปถ: ${report.file}\n`
output += ` โฑ๏ธ ๆถ้ด: ${new Date(report.timestamp).toLocaleString()}\n\n`
output += ' โโโโ ้ช่ฏ็ปๆ โโโโ\n\n'
for (const result of report.results) {
const label = TYPE_LABELS[result.type]
const status = STATUS_LABELS[result.status]
const icon = result.passed ? 'โ
' : 'โ'
output += ` ${icon} ${label}\n`
output += ` ็ถๆ: ${status}\n`
output += ` ่ๆถ: ${result.duration}ms\n`
if (result.issues.length > 0) {
output += ' ้ฎ้ข:\n'
for (const issue of result.issues) {
const typeIcon = issue.type === 'error' ? 'โ' : issue.type === 'warning' ? 'โ ๏ธ' : 'โน๏ธ'
output += ` ${typeIcon} ${issue.message}\n`
if (issue.location) {
output += ` ไฝ็ฝฎ: ${issue.location.file}`
if (issue.location.line) {
output += `:${issue.location.line}`
}
output += '\n'
}
if (issue.suggestion) {
output += ` ๅปบ่ฎฎ: ${issue.suggestion}\n`
}
}
}
output += '\n'
}
output += ' โโโโ ๆ่ฆ โโโโ\n\n'
output += ` ๐ ๆป่ฎก: ${report.summary.total}\n`
output += ` โ
้่ฟ: ${report.summary.passed}\n`
if (report.summary.failed > 0) {
output += ` โ ๅคฑ่ดฅ: ${report.summary.failed}\n`
}
if (report.summary.warnings > 0) {
output += ` โ ๏ธ ่ญฆๅ: ${report.summary.warnings}\n`
}
output += '\n'
const overallIcon = report.overallPassed ? 'โ
' : 'โ'
output += ` ${overallIcon} ๆดไฝ็ปๆ: ${report.overallPassed ? '้่ฟ' : 'ๆช้่ฟ'}\n`
return output
}
/**
* ๆ ผๅผๅ็ฎๅๆ่ฆ
*/
export function formatSummary(report: VerificationReport): string {
const icon = report.overallPassed ? 'โ
' : 'โ'
const passed = report.summary.passed
const total = report.summary.total
const failed = report.summary.failed
const warnings = report.summary.warnings
let summary = `${icon} ้ช่ฏ ${passed}/${total}`
if (failed > 0) {
summary += ` | โ ${failed} ้กนๅคฑ่ดฅ`
}
if (warnings > 0) {
summary += ` | โ ๏ธ ${warnings} ้กน่ญฆๅ`
}
return summary
}
/**
* ่ทๅๅคฑ่ดฅ็้ฎ้ขๅ่กจ
*/
export function getFailedIssues(report: VerificationReport): VerificationIssue[] {
const issues: VerificationIssue[] = []
for (const result of report.results) {
if (!result.passed) {
issues.push(...result.issues.filter(i => i.type === 'error'))
}
}
return issues
}
/**
* ๆฃๆฅๆฏๅฆ้่ฆๅคฑ่ดฅ
*/
export function shouldFail(
report: VerificationReport,
options: VerificationOptions
): boolean {
// ๅฆๆๆไปปไฝ้ช่ฏๅคฑ่ดฅ
if (report.summary.failed > 0) {
return true
}
// ๆฃๆฅ่ญฆๅๆฏๅฆๅฏผ่ดๅคฑ่ดฅ
if (options.failOnWarning && report.summary.warnings > 0) {
return true
}
return false
}