use forjar::core::scoring::{compute, RuntimeData, ScoringInput};
use forjar::core::types::ForjarConfig;
fn empty_config() -> ForjarConfig {
ForjarConfig {
version: "1.0".into(),
name: "test".into(),
..Default::default()
}
}
fn runtime_input(runtime: RuntimeData) -> ScoringInput {
ScoringInput {
status: "qualified".into(),
idempotency: "strong".into(),
budget_ms: 5000,
runtime: Some(runtime),
raw_yaml: Some(String::new()),
}
}
fn perfect_runtime() -> RuntimeData {
RuntimeData {
validate_pass: true,
plan_pass: true,
first_apply_pass: true,
second_apply_pass: true,
zero_changes_on_reapply: true,
hash_stable: true,
all_resources_converged: true,
state_lock_written: true,
warning_count: 0,
changed_on_reapply: 0,
first_apply_ms: 1000,
second_apply_ms: 50,
}
}
fn zero_runtime() -> RuntimeData {
RuntimeData {
validate_pass: false,
plan_pass: false,
first_apply_pass: false,
second_apply_pass: false,
zero_changes_on_reapply: false,
hash_stable: false,
all_resources_converged: false,
state_lock_written: false,
warning_count: 0,
changed_on_reapply: 0,
first_apply_ms: 0,
second_apply_ms: 0,
}
}
fn find_dim<'a>(
result: &'a forjar::core::scoring::ScoringResult,
code: &str,
) -> &'a forjar::core::scoring::DimensionScore {
result.dimensions.iter().find(|d| d.code == code).unwrap()
}
#[test]
fn cor_perfect_runtime() {
let config = empty_config();
let input = runtime_input(perfect_runtime());
let result = compute(&config, &input);
let cor = find_dim(&result, "COR");
assert_eq!(cor.score, 95);
}
#[test]
fn cor_zero_runtime() {
let config = empty_config();
let input = runtime_input(zero_runtime());
let result = compute(&config, &input);
let cor = find_dim(&result, "COR");
assert_eq!(cor.score, 0);
}
#[test]
fn cor_only_validate_and_plan() {
let config = empty_config();
let mut rt = zero_runtime();
rt.validate_pass = true;
rt.plan_pass = true;
let input = runtime_input(rt);
let result = compute(&config, &input);
let cor = find_dim(&result, "COR");
assert_eq!(cor.score, 30); }
#[test]
fn cor_warnings_deduct() {
let config = empty_config();
let mut rt = perfect_runtime();
rt.warning_count = 5;
let input = runtime_input(rt);
let result = compute(&config, &input);
let cor = find_dim(&result, "COR");
assert_eq!(cor.score, 85);
}
#[test]
fn cor_warnings_capped_at_5() {
let config = empty_config();
let mut rt = perfect_runtime();
rt.warning_count = 100;
let input = runtime_input(rt);
let result = compute(&config, &input);
let cor = find_dim(&result, "COR");
assert_eq!(cor.score, 85);
}
#[test]
fn cor_no_runtime_zero() {
let config = empty_config();
let input = ScoringInput {
status: "qualified".into(),
idempotency: "strong".into(),
budget_ms: 5000,
runtime: None,
raw_yaml: Some(String::new()),
};
let result = compute(&config, &input);
let cor = find_dim(&result, "COR");
assert_eq!(cor.score, 0);
}
#[test]
fn idm_perfect_strong() {
let config = empty_config();
let input = runtime_input(perfect_runtime());
let result = compute(&config, &input);
let idm = find_dim(&result, "IDM");
assert_eq!(idm.score, 90);
}
#[test]
fn idm_weak_class() {
let config = empty_config();
let rt = perfect_runtime();
let mut input = runtime_input(rt);
input.idempotency = "weak".into();
let result = compute(&config, &input);
let idm = find_dim(&result, "IDM");
assert_eq!(idm.score, 80);
}
#[test]
fn idm_eventual_class() {
let config = empty_config();
let rt = perfect_runtime();
let mut input = runtime_input(rt);
input.idempotency = "eventual".into();
let result = compute(&config, &input);
let idm = find_dim(&result, "IDM");
assert_eq!(idm.score, 70);
}
#[test]
fn idm_changed_on_reapply_deduction() {
let config = empty_config();
let mut rt = perfect_runtime();
rt.changed_on_reapply = 3;
let input = runtime_input(rt);
let result = compute(&config, &input);
let idm = find_dim(&result, "IDM");
assert_eq!(idm.score, 60);
}
#[test]
fn idm_changed_on_reapply_capped() {
let config = empty_config();
let mut rt = perfect_runtime();
rt.changed_on_reapply = 100;
let input = runtime_input(rt);
let result = compute(&config, &input);
let idm = find_dim(&result, "IDM");
assert_eq!(idm.score, 40);
}
#[test]
fn idm_zero_runtime() {
let config = empty_config();
let input = runtime_input(zero_runtime());
let result = compute(&config, &input);
let idm = find_dim(&result, "IDM");
assert_eq!(idm.score, 20);
}
#[test]
fn prf_fast_within_budget() {
let config = empty_config();
let mut rt = perfect_runtime();
rt.first_apply_ms = 1000; rt.second_apply_ms = 50; let input = runtime_input(rt);
let result = compute(&config, &input);
let prf = find_dim(&result, "PRF");
assert_eq!(prf.score, 100);
}
#[test]
fn prf_over_budget() {
let config = empty_config();
let mut rt = perfect_runtime();
rt.first_apply_ms = 10000; rt.second_apply_ms = 50;
let input = runtime_input(rt);
let result = compute(&config, &input);
let prf = find_dim(&result, "PRF");
assert_eq!(prf.score, 50);
}
#[test]
fn prf_no_budget_zero() {
let config = empty_config();
let rt = perfect_runtime();
let mut input = runtime_input(rt);
input.budget_ms = 0;
let result = compute(&config, &input);
let prf = find_dim(&result, "PRF");
assert_eq!(prf.score, 0);
}
#[test]
fn prf_slow_idempotent() {
let config = empty_config();
let mut rt = perfect_runtime();
rt.first_apply_ms = 2000;
rt.second_apply_ms = 15000; let input = runtime_input(rt);
let result = compute(&config, &input);
let prf = find_dim(&result, "PRF");
assert_eq!(prf.score, 50);
}
#[test]
fn prf_budget_breakpoints() {
let config = empty_config();
let mut rt = perfect_runtime();
rt.first_apply_ms = 3000; rt.second_apply_ms = 100;
let input = runtime_input(rt);
let result = compute(&config, &input);
let prf = find_dim(&result, "PRF");
assert_eq!(prf.score, 90);
}
#[test]
fn prf_budget_76_100_bracket() {
let config = empty_config();
let mut rt = perfect_runtime();
rt.first_apply_ms = 4500; rt.second_apply_ms = 100;
let input = runtime_input(rt);
let result = compute(&config, &input);
let prf = find_dim(&result, "PRF");
assert_eq!(prf.score, 80);
}
#[test]
fn prf_budget_101_150_bracket() {
let config = empty_config();
let mut rt = perfect_runtime();
rt.first_apply_ms = 6000; rt.second_apply_ms = 100;
let input = runtime_input(rt);
let result = compute(&config, &input);
let prf = find_dim(&result, "PRF");
assert_eq!(prf.score, 65);
}
#[test]
fn prf_idempotent_breakpoints() {
let config = empty_config();
let mut rt = perfect_runtime();
rt.first_apply_ms = 1000;
rt.second_apply_ms = 3000;
let input = runtime_input(rt);
let result = compute(&config, &input);
let prf = find_dim(&result, "PRF");
assert_eq!(prf.score, 75);
}
#[test]
fn prf_idempotent_5001_10000() {
let config = empty_config();
let mut rt = perfect_runtime();
rt.first_apply_ms = 1000;
rt.second_apply_ms = 7000;
let input = runtime_input(rt);
let result = compute(&config, &input);
let prf = find_dim(&result, "PRF");
assert_eq!(prf.score, 65);
}
#[test]
fn grade_a_requires_90_and_min_80() {
let config = empty_config();
let mut rt = perfect_runtime();
rt.first_apply_ms = 1000;
rt.second_apply_ms = 50;
let input = runtime_input(rt);
let result = compute(&config, &input);
assert!(result.runtime_grade.is_some());
let rg = result.runtime_grade.unwrap();
assert_eq!(rg, 'A');
}
#[test]
fn grade_format_static_runtime() {
let config = empty_config();
let input = runtime_input(perfect_runtime());
let result = compute(&config, &input);
assert!(result.grade.contains('/'));
let parts: Vec<&str> = result.grade.split('/').collect();
assert_eq!(parts.len(), 2);
}
#[test]
fn grade_pending_without_runtime() {
let config = empty_config();
let input = ScoringInput {
status: "qualified".into(),
idempotency: "strong".into(),
budget_ms: 0,
runtime: None,
raw_yaml: Some(String::new()),
};
let result = compute(&config, &input);
assert!(result.grade.ends_with("/pending"));
}
#[test]
fn grade_blocked_status() {
let config = empty_config();
let input = ScoringInput {
status: "blocked".into(),
idempotency: "strong".into(),
budget_ms: 0,
runtime: None,
raw_yaml: Some(String::new()),
};
let result = compute(&config, &input);
assert!(result.grade.ends_with("/blocked"));
assert!(result.hard_fail);
assert!(result
.hard_fail_reason
.as_ref()
.unwrap()
.contains("blocked"));
}
#[test]
fn cor_weight_is_35_pct() {
let config = empty_config();
let input = runtime_input(perfect_runtime());
let result = compute(&config, &input);
let cor = find_dim(&result, "COR");
assert!((cor.weight - 0.35).abs() < 0.001);
}
#[test]
fn idm_weight_is_35_pct() {
let config = empty_config();
let input = runtime_input(perfect_runtime());
let result = compute(&config, &input);
let idm = find_dim(&result, "IDM");
assert!((idm.weight - 0.35).abs() < 0.001);
}
#[test]
fn prf_weight_is_30_pct() {
let config = empty_config();
let input = runtime_input(perfect_runtime());
let result = compute(&config, &input);
let prf = find_dim(&result, "PRF");
assert!((prf.weight - 0.30).abs() < 0.001);
}
#[test]
fn legacy_composite_blends_all_8() {
let config = empty_config();
let input = runtime_input(perfect_runtime());
let result = compute(&config, &input);
assert_eq!(result.dimensions.len(), 8);
assert!(result.composite > 0);
}
#[test]
fn runtime_composite_present_with_runtime() {
let config = empty_config();
let input = runtime_input(perfect_runtime());
let result = compute(&config, &input);
assert!(result.runtime_composite.is_some());
assert!(result.runtime_composite.unwrap() > 0);
}
#[test]
fn runtime_composite_absent_without_runtime() {
let config = empty_config();
let input = ScoringInput {
status: "qualified".into(),
idempotency: "strong".into(),
budget_ms: 0,
runtime: None,
raw_yaml: Some(String::new()),
};
let result = compute(&config, &input);
assert!(result.runtime_composite.is_none());
assert!(result.runtime_grade.is_none());
}