File size: 5,387 Bytes
c3f6bab | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | """
tests/test_safety_classifier.py
──────────────────────────────
Unit tests for the regex-based SafetyClassifier.
Run with: python -m pytest tests/ -v
"""
import sys, os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
import pytest
from safety_classifier import SafetyClassifier, ClassificationResult
clf = SafetyClassifier()
# ── Helpers ───────────────────────────────────────────────────────────────────
def is_safe(text: str) -> bool:
return clf.classify(text).label == "SAFE"
def is_dangerous(text: str) -> bool:
return clf.classify(text).label == "DANGEROUS"
def categories(text: str) -> list[str]:
return clf.classify(text).hazards
# ── SAFE cases ────────────────────────────────────────────────────────────────
class TestSafeCaptions:
def test_normal_street(self):
assert is_safe("A quiet residential street with parked cars and green trees.")
def test_indoor_office(self):
assert is_safe("An office with desks, computers, and people working quietly.")
def test_park_scene(self):
assert is_safe("Children playing in a sunny park near a fountain.")
def test_kitchen(self):
assert is_safe("A clean kitchen with a counter, sink, and hanging pots.")
def test_empty_caption(self):
assert is_safe("")
def test_whitespace_only(self):
assert is_safe(" ")
# ── DANGEROUS cases ───────────────────────────────────────────────────────────
class TestDangerousCaptions:
# Fire
def test_fire(self):
assert is_dangerous("There is a large fire burning near the building.")
assert "fire" in categories("Flames are visible through the window.")
def test_smoke(self):
assert is_dangerous("The room is filled with thick smoke.")
# Flood
def test_flooding(self):
assert is_dangerous("The street is flooding rapidly after heavy rain.")
assert "flood" in categories("Water is flooding into the basement.")
# Weapons
def test_gun(self):
assert is_dangerous("A man is holding a pistol near the entrance.")
assert "weapon" in categories("A rifle is leaning against the wall.")
def test_knife(self):
assert is_dangerous("Someone is brandishing a knife in the crowd.")
# Vehicle crash
def test_crash(self):
assert is_dangerous("Two cars have been involved in a collision on the road.")
assert "crash" in categories("There is an overturned truck blocking the highway.")
# Oncoming traffic
def test_oncoming_vehicle(self):
assert is_dangerous("An oncoming car is speeding directly toward the pedestrian.")
# Violence
def test_fight(self):
assert is_dangerous("A brawl has broken out in front of the store.")
# Falls & heights
def test_cliff(self):
assert is_dangerous("The person is standing at the edge of a cliff.")
assert "fall" in categories("A steep drop is just ahead on the trail.")
# Injury / blood
def test_blood(self):
assert is_dangerous("There is blood visible on the floor near the door.")
# Electrical
def test_exposed_wire(self):
assert is_dangerous("An exposed wire is hanging from the ceiling.")
# Slip hazard
def test_wet_floor(self):
assert is_dangerous("The wet floor near the entrance presents a slip hazard.")
# Storm
def test_storm(self):
assert is_dangerous("A tornado is approaching from the west.")
# Chemical
def test_chemical_spill(self):
assert is_dangerous("There is a chemical spill near the laboratory bench.")
# Generic danger keywords
def test_generic_danger(self):
assert is_dangerous("This is a dangerous situation requiring immediate evacuation.")
# ── Edge cases ────────────────────────────────────────────────────────────────
class TestEdgeCases:
def test_case_insensitive(self):
assert is_dangerous("FIRE is spreading across the building.")
assert is_dangerous("There is a KNIFE on the ground.")
def test_multiple_hazards(self):
r = clf.classify("Flooding and fire are both present, and there is broken glass from the crash.")
assert r.is_dangerous
assert len(r.hazards) >= 2
def test_explain_method(self):
breakdown = clf.explain("A fire is burning and an exposed wire is visible.")
assert "fire" in breakdown
assert "electrical" in breakdown
def test_partial_word_no_match(self):
# "firing" a weapon is different from "fire" — ensure no false positive
# (pattern uses \b word boundaries)
r = clf.classify("The CEO is firing employees in the boardroom.")
# "firing" does NOT match \bfire\b — should be SAFE
assert r.label == "SAFE"
|