Spaces:
Running on Zero
Running on Zero
| import sys, os | |
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) | |
| from core.validation import ( | |
| safe_parse_llm_json, ValidationError, clamp, coerce_int, coerce_float, | |
| coerce_need_types, validate_image_file, validate_report_text, | |
| ) | |
| def test_parses_clean_json(): | |
| data = safe_parse_llm_json('{"people_affected": 10, "urgency": 5, "need_types": ["medical"]}', | |
| required_keys=["people_affected", "urgency"]) | |
| assert data["people_affected"] == 10 | |
| print("PASS: clean JSON parses correctly") | |
| def test_parses_json_wrapped_in_prose_and_fences(): | |
| raw = 'Sure, here is the JSON:\n```json\n{"people_affected": 7, "urgency": 3}\n```\nLet me know if you need more.' | |
| data = safe_parse_llm_json(raw, required_keys=["people_affected", "urgency"]) | |
| assert data["people_affected"] == 7 | |
| print("PASS: JSON wrapped in markdown fences + prose is correctly extracted") | |
| def test_raises_on_missing_required_keys(): | |
| try: | |
| safe_parse_llm_json('{"people_affected": 5}', required_keys=["people_affected", "urgency"]) | |
| assert False, "should have raised" | |
| except ValidationError: | |
| print("PASS: missing required key raises ValidationError") | |
| def test_raises_on_empty_output(): | |
| try: | |
| safe_parse_llm_json("", required_keys=["x"]) | |
| assert False, "should have raised" | |
| except ValidationError: | |
| print("PASS: empty model output raises ValidationError") | |
| def test_raises_on_garbage_output(): | |
| try: | |
| safe_parse_llm_json("I cannot help with that request.", required_keys=["x"]) | |
| assert False, "should have raised" | |
| except ValidationError: | |
| print("PASS: non-JSON garbage output raises ValidationError") | |
| def test_coerce_int_clamps_and_defaults(): | |
| assert coerce_int("12", lo=0, hi=10) == 10 | |
| assert coerce_int(-5, lo=0, hi=10) == 0 | |
| assert coerce_int("not a number", default=3) == 3 | |
| print("PASS: coerce_int clamps and falls back on garbage") | |
| def test_coerce_float_clamps(): | |
| assert coerce_float(99, lo=0, hi=10) == 10 | |
| assert coerce_float(None, default=5.0) == 5.0 | |
| print("PASS: coerce_float clamps and falls back on garbage") | |
| def test_coerce_need_types_filters_unknown_values(): | |
| result = coerce_need_types(["medical", "teleportation", "rescue", "medical"]) | |
| assert result == ["medical", "rescue"], f"got {result}" | |
| print("PASS: coerce_need_types filters unknown values and dedupes") | |
| def test_validate_report_text_handles_empty_and_long(): | |
| text, warning = validate_report_text("") | |
| assert text == "" and warning | |
| print("PASS: empty report text flagged with warning") | |
| long_text = "x" * 5000 | |
| text, warning = validate_report_text(long_text, max_chars=4000) | |
| assert len(text) == 4000 and "truncated" in warning | |
| print("PASS: overlong report text truncated with warning") | |
| def test_validate_image_file_missing(): | |
| is_valid, err = validate_image_file("/nonexistent/path/image.png") | |
| assert not is_valid and err | |
| print("PASS: missing image file correctly flagged invalid") | |
| def test_clamp(): | |
| assert clamp(15, 0, 10) == 10 | |
| assert clamp(-5, 0, 10) == 0 | |
| assert clamp(5, 0, 10) == 5 | |
| print("PASS: clamp works at both bounds and in range") | |
| 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)} validation tests passed.") | |