Spaces:
Sleeping
Sleeping
KevinIsInCoding
test(critic-fixes): address brittleness, over-mocking, and missing edge cases (#20)
3d5e588 unverified | """Tests for models.py β pure deterministic functions only.""" | |
| from __future__ import annotations | |
| import math | |
| import pytest | |
| from models import PatientProfile, geocode_zip, haversine_miles | |
| def minimal_patient(**kwargs): | |
| """Minimal PatientProfile factory β callers only specify fields that vary.""" | |
| def _make(**overrides): | |
| defaults = dict(disease="ALS", age=45, onset_months=6, zip_code="10001", lat=40.75, lon=-73.99) | |
| defaults.update(overrides) | |
| return PatientProfile(**defaults) | |
| return _make | |
| # --------------------------------------------------------------------------- | |
| # haversine_miles | |
| # --------------------------------------------------------------------------- | |
| class TestHaversineMiles: | |
| def test_same_point_is_zero(self): | |
| assert haversine_miles(42.0, -71.0, 42.0, -71.0) == 0.0 | |
| def test_known_distance_boston_nyc(self): | |
| # Boston (42.3601, -71.0589) to NYC (40.7128, -74.0060) β 190 miles | |
| dist = haversine_miles(42.3601, -71.0589, 40.7128, -74.0060) | |
| assert 185 < dist < 195 | |
| def test_symmetry(self): | |
| d1 = haversine_miles(42.0, -71.0, 34.0, -118.0) | |
| d2 = haversine_miles(34.0, -118.0, 42.0, -71.0) | |
| assert math.isclose(d1, d2, rel_tol=1e-9) | |
| def test_short_distance(self): | |
| # Two points ~1 mile apart | |
| dist = haversine_miles(42.3370, -71.1061, 42.3514, -71.1061) | |
| assert 0.8 < dist < 1.2 | |
| def test_returns_float(self): | |
| result = haversine_miles(0.0, 0.0, 0.0, 1.0) | |
| assert isinstance(result, float) | |
| # --------------------------------------------------------------------------- | |
| # PatientProfile.summary | |
| # --------------------------------------------------------------------------- | |
| class TestPatientProfileSummary: | |
| def test_summary_contains_disease(self, als_patient): | |
| assert "Amyotrophic Lateral Sclerosis" in als_patient.summary() | |
| def test_summary_contains_age(self, als_patient): | |
| assert "52" in als_patient.summary() | |
| def test_summary_contains_onset_months(self, als_patient): | |
| assert "18" in als_patient.summary() | |
| def test_summary_contains_diagnosis_months(self, als_patient): | |
| assert "12" in als_patient.summary() | |
| def test_summary_contains_zip(self, als_patient): | |
| assert "02115" in als_patient.summary() | |
| def test_summary_contains_radius(self, als_patient): | |
| assert "100" in als_patient.summary() | |
| def test_summary_contains_benchmarks(self, als_patient): | |
| text = als_patient.summary() | |
| assert "alsfrs_r" in text | |
| assert "38" in text | |
| def test_summary_no_benchmarks(self, minimal_patient): | |
| assert "Benchmarks" not in minimal_patient().summary() | |
| def test_summary_phase_labels(self, minimal_patient): | |
| text = minimal_patient(phases=["2", "3", "0", "na"]).summary() | |
| assert "Phase 2" in text | |
| assert "Phase 3" in text | |
| assert "Early Phase 1" in text | |
| assert "Not Applicable" in text | |
| def test_summary_study_type_defaults(self, minimal_patient): | |
| text = minimal_patient().summary() | |
| assert "Clinical trials" in text | |
| assert "Observational" not in text | |
| assert "EAP" not in text | |
| def test_summary_include_observational(self, minimal_patient): | |
| assert "Observational" in minimal_patient(include_observational=True).summary() | |
| def test_summary_include_eap(self, minimal_patient): | |
| assert "EAP" in minimal_patient(include_eap=True).summary() | |
| def test_summary_returns_string(self, als_patient): | |
| assert isinstance(als_patient.summary(), str) | |
| def test_summary_no_phases(self, minimal_patient): | |
| assert "Phases:" not in minimal_patient().summary() | |
| # --------------------------------------------------------------------------- | |
| # geocode_zip β httpx mocked | |
| # --------------------------------------------------------------------------- | |
| class TestGeocodeZip: | |
| def test_returns_lat_lon_from_response(self, httpx_mock): | |
| httpx_mock.add_response(json=[{"lat": "42.3370", "lon": "-71.1061"}]) | |
| lat, lon = geocode_zip("02115", "US") | |
| assert lat == pytest.approx(42.3370) | |
| assert lon == pytest.approx(-71.1061) | |
| def test_empty_results_raises_value_error(self, httpx_mock): | |
| httpx_mock.add_response(json=[]) | |
| with pytest.raises(ValueError, match="Cannot geocode"): | |
| geocode_zip("00000", "US") | |