Files
claw/tests/scene_generator_family_policy_test.rs

122 lines
3.8 KiB
Rust

use std::fs;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct FamilyResults {
#[serde(rename = "generatedAt")]
generated_at: String,
scope: String,
families: Vec<FamilyResult>,
}
#[derive(Debug, Deserialize)]
struct FamilyResult {
id: String,
group: String,
#[serde(rename = "familyName")]
family_name: String,
#[serde(rename = "representativeRuns")]
representative_runs: u32,
#[serde(rename = "expansionRuns", default)]
expansion_runs: u32,
#[serde(rename = "candidateBatchCount", default)]
candidate_batch_count: u32,
#[serde(rename = "passedRuns")]
passed_runs: u32,
#[serde(rename = "failedRuns")]
failed_runs: u32,
#[serde(rename = "successRate")]
success_rate: f64,
#[serde(rename = "failureTaxonomy")]
failure_taxonomy: Vec<String>,
notes: Vec<String>,
}
#[derive(Debug, Deserialize)]
struct FamilyExpansionPolicy {
#[serde(rename = "policyVersion")]
policy_version: String,
scope: String,
#[serde(rename = "mainlineGroups")]
mainline_groups: Vec<GroupPolicy>,
#[serde(rename = "boundaryGroups", default)]
boundary_groups: Vec<GroupPolicy>,
#[serde(rename = "deferredGroups")]
deferred_groups: Vec<GroupPolicy>,
}
#[derive(Debug, Deserialize)]
struct GroupPolicy {
group: String,
policy: String,
#[serde(rename = "executionRule")]
execution_rule: String,
#[serde(rename = "acceptanceFocus", default)]
acceptance_focus: Vec<String>,
}
#[test]
fn family_results_asset_is_actionable() {
let results: FamilyResults = serde_json::from_str(
&fs::read_to_string("tests/fixtures/generated_scene/p1_family_results.json").unwrap(),
)
.unwrap();
assert!(!results.generated_at.is_empty());
assert!(results.scope.contains("representative"));
assert_eq!(results.families.len(), 7);
for family in results.families {
assert!(matches!(
family.group.as_str(),
"G1" | "G2" | "G3" | "G6" | "G7" | "G8"
));
assert!(!family.id.is_empty());
assert!(!family.family_name.is_empty());
assert!(family.representative_runs >= 1);
assert!(family.candidate_batch_count <= 102);
assert_eq!(
family.representative_runs + family.expansion_runs,
family.passed_runs + family.failed_runs
);
assert!(family.success_rate >= 0.0 && family.success_rate <= 1.0);
assert!(!family.failure_taxonomy.is_empty());
assert!(!family.notes.is_empty());
}
}
#[test]
fn family_expansion_policy_matches_mainline_scope() {
let policy: FamilyExpansionPolicy = serde_json::from_str(
&fs::read_to_string("tests/fixtures/generated_scene/family_expansion_policy.json").unwrap(),
)
.unwrap();
assert!(!policy.policy_version.is_empty());
assert_eq!(policy.scope, "roadmap-plan-track-e");
assert_eq!(policy.mainline_groups.len(), 3);
assert_eq!(policy.boundary_groups.len(), 3);
assert_eq!(policy.deferred_groups.len(), 2);
for group in &policy.mainline_groups {
assert!(matches!(group.group.as_str(), "G1" | "G2" | "G3"));
assert_eq!(group.policy, "mainline");
assert!(!group.execution_rule.is_empty());
assert!(!group.acceptance_focus.is_empty());
}
for group in &policy.boundary_groups {
assert!(matches!(group.group.as_str(), "G6" | "G7" | "G8"));
assert_eq!(group.policy, "boundary-runtime");
assert!(!group.execution_rule.is_empty());
assert!(!group.acceptance_focus.is_empty());
}
for group in &policy.deferred_groups {
assert!(matches!(group.group.as_str(), "G4" | "G5"));
assert!(matches!(group.policy.as_str(), "deferred" | "degraded"));
assert!(!group.execution_rule.is_empty());
}
}