upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/grasp-audit/src/result.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-11-28 02:19:47 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2025-11-28 02:19:47 +0000
commit43e53b4ccd9fcebf20cc9c1bdbfe568ddd8051b9 (patch)
tree4aea212e5b1d307affb8e0ce5db1cc898e217889 /grasp-audit/src/result.rs
parentf053827e0a157f348d9cf834f026a8de322abfe2 (diff)
grasp-audit improve cli output eg. add colors and condense
Diffstat (limited to 'grasp-audit/src/result.rs')
-rw-r--r--grasp-audit/src/result.rs76
1 files changed, 61 insertions, 15 deletions
diff --git a/grasp-audit/src/result.rs b/grasp-audit/src/result.rs
index de377e5..2bec5c8 100644
--- a/grasp-audit/src/result.rs
+++ b/grasp-audit/src/result.rs
@@ -1,7 +1,32 @@
1//! Test result types 1//! Test result types
2 2
3use std::collections::BTreeMap;
3use std::time::{Duration, Instant}; 4use std::time::{Duration, Instant};
4 5
6// ANSI color codes
7const GREEN: &str = "\x1b[32m";
8const RED: &str = "\x1b[31m";
9const RESET: &str = "\x1b[0m";
10const BOLD: &str = "\x1b[1m";
11
12/// Extract spec category from a spec_ref by removing trailing test number
13/// e.g., "GRASP-01:event-acceptance:1.1" -> "GRASP-01:event-acceptance"
14/// e.g., "NIP-01:basic:2" -> "NIP-01:basic"
15fn extract_spec_category(spec_ref: &str) -> String {
16 let parts: Vec<&str> = spec_ref.split(':').collect();
17 if parts.len() >= 2 {
18 // Check if the last part looks like a test number (starts with digit)
19 if let Some(last) = parts.last() {
20 if last.chars().next().map(|c| c.is_ascii_digit()).unwrap_or(false) {
21 // Remove the trailing number part
22 return parts[..parts.len() - 1].join(":");
23 }
24 }
25 }
26 // Return as-is if no trailing number found
27 spec_ref.to_string()
28}
29
5/// Result of a single test 30/// Result of a single test
6#[derive(Debug, Clone)] 31#[derive(Debug, Clone)]
7pub struct TestResult { 32pub struct TestResult {
@@ -108,34 +133,55 @@ impl AuditResult {
108 self.results.len() 133 self.results.len()
109 } 134 }
110 135
111 /// Print a detailed report 136 /// Print a detailed report with tests grouped by spec_ref
112 pub fn print_report(&self) { 137 pub fn print_report(&self) {
113 println!("\n{}", self.spec); 138 println!("\n{}{}{}", BOLD, self.spec, RESET);
114 println!("{}", "═".repeat(60)); 139 println!("{}", "═".repeat(60));
115 println!();
116 140
117 let passed = self.passed_count(); 141 let passed = self.passed_count();
118 let total = self.total_count(); 142 let total = self.total_count();
119 143
144 // Group results by spec category (strip trailing test number like ":1.1")
145 let mut grouped: BTreeMap<String, Vec<&TestResult>> = BTreeMap::new();
120 for result in &self.results { 146 for result in &self.results {
121 let status = if result.passed { "✓" } else { "✗" }; 147 // Extract category from spec_ref (e.g., "GRASP-01:event-acceptance:1.1" -> "GRASP-01:event-acceptance")
148 let category = extract_spec_category(&result.spec_ref);
149 grouped
150 .entry(category)
151 .or_default()
152 .push(result);
153 }
122 154
123 println!("{} {} ({})", status, result.name, result.spec_ref); 155 // Print grouped results
124 println!(" Requirement: {}", result.requirement); 156 for (category, results) in &grouped {
157 println!("\n{}[{}]{}", BOLD, category, RESET);
125 158
126 if let Some(error) = &result.error { 159 for result in results {
127 println!(" Error: {}", error); 160 let (color, status) = if result.passed {
128 } 161 (GREEN, "✓")
162 } else {
163 (RED, "✗")
164 };
165
166 println!(" {}{} {}{}", color, status, result.name, RESET);
129 167
130 println!(" Duration: {:?}", result.duration); 168 if let Some(error) = &result.error {
131 println!(); 169 println!(" {}Error: {}{}", RED, error, RESET);
170 }
171 }
132 } 172 }
133 173
134 println!( 174 println!();
135 "Results: {}/{} passed ({:.1}%)", 175 let pass_rate = if total > 0 {
136 passed,
137 total,
138 (passed as f64 / total as f64) * 100.0 176 (passed as f64 / total as f64) * 100.0
177 } else {
178 0.0
179 };
180
181 let summary_color = if passed == total { GREEN } else { RED };
182 println!(
183 "{}Results: {}/{} passed ({:.1}%){}",
184 summary_color, passed, total, pass_rate, RESET
139 ); 185 );
140 println!(); 186 println!();
141 } 187 }