Files
claw/tests/scene_ledger_snapshot_test.rs

139 lines
4.5 KiB
Rust

use std::fs;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct SceneLedgerSnapshot {
#[serde(rename = "snapshotDate")]
snapshot_date: String,
#[serde(rename = "sourceWorkbook")]
source_workbook: String,
#[serde(rename = "generatedAt")]
generated_at: String,
summary: LedgerSummary,
#[serde(rename = "groupingResultCounts")]
grouping_result_counts: std::collections::BTreeMap<String, u32>,
#[serde(rename = "familyJudgementCounts")]
family_judgement_counts: std::collections::BTreeMap<String, u32>,
#[serde(rename = "validatedEntries")]
validated_entries: Vec<ValidatedEntry>,
#[serde(rename = "alignmentNotes")]
alignment_notes: Vec<String>,
}
#[derive(Debug, Deserialize)]
struct LedgerSummary {
#[serde(rename = "totalScenes")]
total_scenes: u32,
#[serde(rename = "validatedScenes")]
validated_scenes: u32,
#[serde(rename = "notYetValidatedScenes")]
not_yet_validated_scenes: u32,
#[serde(rename = "passedRealSample")]
passed_real_sample: u32,
#[serde(rename = "failedRealSample")]
failed_real_sample: u32,
#[serde(rename = "failClosedScenes")]
fail_closed_scenes: u32,
#[serde(rename = "reassignedBoundaryScenes")]
reassigned_boundary_scenes: u32,
}
#[derive(Debug, Deserialize)]
struct ValidatedEntry {
#[serde(rename = "sceneName")]
scene_name: String,
#[serde(rename = "targetFamily")]
target_family: String,
#[serde(rename = "groupingResult")]
grouping_result: String,
#[serde(rename = "validationStatus")]
validation_status: String,
#[serde(rename = "validationResult")]
validation_result: String,
}
#[test]
fn scene_ledger_snapshot_is_actionable() {
let snapshot = load_snapshot();
assert_eq!(snapshot.snapshot_date, "2026-04-18");
assert!(snapshot.source_workbook.ends_with(".xlsx"));
assert_eq!(snapshot.generated_at, "2026-04-18 16:48:05");
assert_eq!(snapshot.summary.total_scenes, 102);
assert_eq!(
snapshot.summary.validated_scenes + snapshot.summary.not_yet_validated_scenes,
snapshot.summary.total_scenes
);
assert_eq!(snapshot.summary.passed_real_sample, 1);
assert_eq!(snapshot.summary.failed_real_sample, 3);
assert_eq!(snapshot.summary.fail_closed_scenes, 2);
assert_eq!(snapshot.summary.reassigned_boundary_scenes, 3);
assert_eq!(
snapshot.validated_entries.len() as u32,
snapshot.summary.validated_scenes
);
assert!(snapshot
.grouping_result_counts
.contains_key("95598/工单家族候选"));
assert!(snapshot.family_judgement_counts.contains_key("待分组"));
assert!(!snapshot.alignment_notes.is_empty());
}
#[test]
fn scene_ledger_snapshot_matches_current_family_asset_baseline() {
let snapshot = load_snapshot();
let has_g1e_pass = snapshot.validated_entries.iter().any(|item| {
item.scene_name == "高低压新增报装容量月度统计表"
&& item.target_family == "G1-E"
&& item.validation_result == "通过"
});
assert!(has_g1e_pass);
let has_g6_boundary = snapshot.validated_entries.iter().any(|item| {
item.scene_name == "电能表现场检验完成率指标报表"
&& item.target_family == "G6"
&& item.validation_result == "已重分组"
});
assert!(has_g6_boundary);
let has_g7_boundary = snapshot.validated_entries.iter().any(|item| {
item.scene_name == "计量资产库存统计"
&& item.target_family == "G7"
&& item.validation_result == "已重分组"
});
assert!(has_g7_boundary);
let has_g8_boundary = snapshot.validated_entries.iter().any(|item| {
item.scene_name == "95598供电服务月报"
&& item.target_family == "G8"
&& item.validation_result == "已重分组"
});
assert!(has_g8_boundary);
let g2_validated = snapshot
.validated_entries
.iter()
.filter(|item| item.target_family == "G2")
.count();
assert_eq!(g2_validated, 3);
let g1e_fail_closed = snapshot
.validated_entries
.iter()
.filter(|item| {
item.target_family.contains("G1-E") && item.validation_result == "Fail-closed"
})
.count();
assert_eq!(g1e_fail_closed, 2);
}
fn load_snapshot() -> SceneLedgerSnapshot {
serde_json::from_str(
&fs::read_to_string("tests/fixtures/generated_scene/scene_ledger_snapshot_2026-04-18.json")
.unwrap(),
)
.unwrap()
}