Skip to main content

garbage_code_hunter/trend/
mod.rs

1//! History trend module.
2//!
3//! Tracks scan results over time and displays quality trends.
4
5pub mod display;
6pub mod history;
7
8use anyhow::Result;
9use history::{HistoryRecord, ToolScore};
10
11pub use crate::common::OutputFormat;
12
13/// Run trend display (load history and show chart).
14pub fn run(last_n: usize, format: &OutputFormat) -> Result<String> {
15    let records = history::load_last(last_n)?;
16
17    let output = match format {
18        OutputFormat::Terminal => display::format_terminal(&records, last_n),
19        OutputFormat::Json => display::format_json(&records),
20    };
21
22    Ok(output)
23}
24
25/// Save a scan result to history.
26pub fn save_scan(
27    project_path: &str,
28    overall_score: f64,
29    tools: Vec<ToolScore>,
30) -> Result<history::HistoryRecord> {
31    let record = HistoryRecord {
32        timestamp: history::now_timestamp(),
33        project_path: project_path.to_string(),
34        overall_score,
35        tools,
36    };
37    history::save(&record)?;
38    Ok(record)
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44
45    #[test]
46    fn test_run_empty_history() {
47        // This test relies on no history existing, which is fine for CI
48        let result = run(10, &OutputFormat::Terminal);
49        assert!(result.is_ok());
50    }
51
52    #[test]
53    fn test_save_and_load() {
54        let tools = vec![
55            ToolScore {
56                name: "code-hunter".to_string(),
57                score: 75.0,
58                item_count: 20,
59            },
60            ToolScore {
61                name: "commit-roaster".to_string(),
62                score: 85.0,
63                item_count: 50,
64            },
65        ];
66        let record = save_scan("/tmp/test-project", 80.0, tools).unwrap();
67        assert_eq!(record.overall_score, 80.0);
68        assert_eq!(record.tools.len(), 2);
69
70        // Verify it was saved
71        let records = history::load_all().unwrap();
72        assert!(records
73            .iter()
74            .any(|r| r.project_path == "/tmp/test-project"));
75    }
76}