Spaces:
Running on Zero
Running on Zero
| import sys, os | |
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) | |
| from core.schemas import VisionAssessment, ReportExtraction | |
| from core.need_engine import build_need_profiles, score_vision_severity | |
| def test_high_confidence_collapse_scores_near_base_severity(): | |
| damage_type, severity = score_vision_severity("Damaged_Infrastructure", confidence=0.95) | |
| assert damage_type == "structural_collapse" | |
| assert severity > 8.0, f"expected high severity for confident structural collapse, got {severity}" | |
| print(f"PASS: confident structural-collapse classification -> severity {severity}") | |
| def test_low_confidence_pulls_toward_neutral(): | |
| _, severity_high_conf = score_vision_severity("Fire_Disaster", confidence=0.95) | |
| _, severity_low_conf = score_vision_severity("Fire_Disaster", confidence=0.20) | |
| assert severity_low_conf < severity_high_conf, "low classifier confidence should pull severity toward neutral, not stay extreme" | |
| print(f"PASS: fire severity at 95% conf = {severity_high_conf}, at 20% conf = {severity_low_conf}") | |
| def test_non_damage_scores_low(): | |
| _, severity = score_vision_severity("Non_Damage", confidence=0.9) | |
| assert severity < 3.0 | |
| print(f"PASS: Non_Damage classification scores low severity ({severity})") | |
| def test_more_people_affected_raises_priority_all_else_equal(): | |
| vision = { | |
| "A": VisionAssessment("A", "structural_collapse", "Damaged_Infrastructure", 0.9, "cap", 8.0), | |
| "B": VisionAssessment("B", "structural_collapse", "Damaged_Infrastructure", 0.9, "cap", 8.0), | |
| } | |
| reports = { | |
| "A": ReportExtraction("A", people_affected=5, need_types=["rescue"], urgency=7), | |
| "B": ReportExtraction("B", people_affected=80, need_types=["rescue"], urgency=7), | |
| } | |
| profiles = build_need_profiles(vision, reports, {"A": "A", "B": "B"}, {"A": (0, 0), "B": (0, 0)}) | |
| a = next(p for p in profiles if p.location_id == "A") | |
| b = next(p for p in profiles if p.location_id == "B") | |
| assert b.priority_score > a.priority_score, "more people affected (all else equal) must raise priority score" | |
| print(f"PASS: A (5 people) priority={a.priority_score}, B (80 people) priority={b.priority_score}") | |
| def test_missing_report_falls_back_gracefully(): | |
| vision = {"A": VisionAssessment("A", "fire", "Fire_Disaster", 0.8, "smoke visible", 7.0)} | |
| profiles = build_need_profiles(vision, {}, {"A": "Zone A"}, {"A": (1.0, 2.0)}) | |
| assert len(profiles) == 1 | |
| assert profiles[0].people_affected == 0 | |
| print("PASS: location with vision data but no report does not crash, defaults people_affected=0") | |
| def test_missing_vision_falls_back_gracefully(): | |
| reports = {"A": ReportExtraction("A", people_affected=15, need_types=["medical"], urgency=6)} | |
| profiles = build_need_profiles({}, reports, {"A": "Zone A"}, {"A": (1.0, 2.0)}) | |
| assert len(profiles) == 1 | |
| assert profiles[0].severity == 5.0 # NEUTRAL_SEVERITY fallback | |
| print("PASS: location with report but no image does not crash, defaults to neutral severity") | |
| def test_profiles_sorted_by_priority_descending(): | |
| vision = { | |
| "A": VisionAssessment("A", "no_significant_damage", "Non_Damage", 0.9, "minor", 1.0), | |
| "B": VisionAssessment("B", "structural_collapse", "Damaged_Infrastructure", 0.95, "collapse", 9.0), | |
| } | |
| reports = { | |
| "A": ReportExtraction("A", people_affected=5, need_types=[], urgency=2), | |
| "B": ReportExtraction("B", people_affected=50, need_types=["medical", "rescue"], urgency=9), | |
| } | |
| profiles = build_need_profiles(vision, reports, {"A": "A", "B": "B"}, {"A": (0, 0), "B": (0, 0)}) | |
| assert profiles[0].location_id == "B", "highest priority location must sort first" | |
| print("PASS: profiles sorted with highest priority first") | |
| if __name__ == "__main__": | |
| tests = [v for k, v in list(globals().items()) if k.startswith("test_")] | |
| for t in tests: | |
| t() | |
| print(f"\n{len(tests)}/{len(tests)} need-engine tests passed.") | |