use reputation_core::Calculator;
use reputation_types::AgentDataBuilder;
use serde::Deserialize;
use std::fs;
use chrono::DateTime;
#[derive(Debug, Deserialize)]
struct TestVectorFile {
#[allow(dead_code)]
version: String,
#[allow(dead_code)]
algorithm: String,
test_cases: Vec<TestCase>,
}
#[derive(Debug, Deserialize)]
struct TestCase {
id: String,
category: String,
#[allow(dead_code)]
description: String,
input: TestInput,
expected: ExpectedScore,
}
#[derive(Debug, Deserialize)]
struct TestInput {
did: String,
created_at: DateTime<chrono::Utc>,
mcp_level: Option<u8>,
identity_verified: bool,
security_audit_passed: bool,
open_source: bool,
total_interactions: u32,
total_reviews: u32,
average_rating: Option<f64>,
}
#[derive(Debug, Deserialize)]
struct ExpectedScore {
score: f64,
confidence: f64,
level: String,
is_provisional: bool,
data_points: u32,
}
#[test]
fn test_validate_all_test_vectors() {
let json = fs::read_to_string("test_vectors.json")
.expect("Failed to read test_vectors.json");
let vectors: TestVectorFile = serde_json::from_str(&json)
.expect("Failed to parse test vectors");
println!("Validating {} test vectors...", vectors.test_cases.len());
let calc = Calculator::default();
let mut failures = Vec::new();
for test_case in &vectors.test_cases {
let mut builder = AgentDataBuilder::new(&test_case.input.did)
.created_at(test_case.input.created_at)
.total_interactions(test_case.input.total_interactions)
.identity_verified(test_case.input.identity_verified)
.security_audit_passed(test_case.input.security_audit_passed)
.open_source(test_case.input.open_source);
if let Some(level) = test_case.input.mcp_level {
builder = builder.mcp_level(level);
}
if test_case.input.total_reviews > 0 {
if let Some(rating) = test_case.input.average_rating {
builder = builder.with_reviews(test_case.input.total_reviews, rating);
}
}
let agent = builder.build().unwrap();
match calc.calculate(&agent) {
Ok(actual) => {
let tolerance = 0.0001;
if (actual.score - test_case.expected.score).abs() > tolerance {
failures.push(format!(
"{}: Score mismatch - expected {}, got {}",
test_case.id, test_case.expected.score, actual.score
));
}
if (actual.confidence - test_case.expected.confidence).abs() > tolerance {
failures.push(format!(
"{}: Confidence mismatch - expected {}, got {}",
test_case.id, test_case.expected.confidence, actual.confidence
));
}
let actual_level = format!("{:?}", actual.level);
if actual_level != test_case.expected.level {
failures.push(format!(
"{}: Level mismatch - expected {}, got {}",
test_case.id, test_case.expected.level, actual_level
));
}
if actual.is_provisional != test_case.expected.is_provisional {
failures.push(format!(
"{}: Provisional flag mismatch - expected {}, got {}",
test_case.id, test_case.expected.is_provisional, actual.is_provisional
));
}
if actual.data_points != test_case.expected.data_points {
failures.push(format!(
"{}: Data points mismatch - expected {}, got {}",
test_case.id, test_case.expected.data_points, actual.data_points
));
}
}
Err(e) => {
failures.push(format!(
"{}: Calculation failed - {:?}",
test_case.id, e
));
}
}
}
if !failures.is_empty() {
eprintln!("\nTest vector validation failures:");
for failure in &failures {
eprintln!(" - {}", failure);
}
panic!("{} test vectors failed validation", failures.len());
}
println!("✅ All {} test vectors validated successfully!", vectors.test_cases.len());
}
#[test]
fn test_vector_categories_coverage() {
let json = fs::read_to_string("test_vectors.json")
.expect("Failed to read test_vectors.json");
let vectors: TestVectorFile = serde_json::from_str(&json)
.expect("Failed to parse test vectors");
let mut category_counts = std::collections::HashMap::new();
for test_case in &vectors.test_cases {
*category_counts.entry(test_case.category.clone()).or_insert(0) += 1;
}
let required_categories = [
("new_agents", 2),
("verified_agents", 5),
("review_patterns", 5),
("confidence_levels", 4),
("edge_cases", 5),
("high_interaction", 3),
];
for (category, min_count) in &required_categories {
let count = category_counts.get(*category).unwrap_or(&0);
assert!(
*count >= *min_count,
"Category '{}' has {} test cases, expected at least {}",
category, count, min_count
);
}
println!("✅ Test vector category coverage verified!");
}