KevinIsInCoding Claude Sonnet 4.6 commited on
Commit
9c9268b
·
unverified ·
1 Parent(s): 01a873b

test(wave-2): add pure-function tests for models and prompts (#17)

Browse files

Covers haversine_miles (5 cases: zero, known distance, symmetry, short,
return type) and PatientProfile.summary (14 cases: all fields, phases,
study types, edge cases). Covers lookup_disease_profile (15 cases: exact
match, case-insensitive, synonyms, multi-disease registry, partial
containment, unknown, structure validation).

All 35 tests pass with no mocks — confirms pytest wiring and that the
data/diseases/ JSON registry is structurally intact.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

Files changed (2) hide show
  1. tests/test_models.py +120 -0
  2. tests/test_prompts.py +98 -0
tests/test_models.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Tests for models.py — pure deterministic functions only."""
2
+ from __future__ import annotations
3
+
4
+ import math
5
+
6
+ import pytest
7
+
8
+ from models import PatientProfile, haversine_miles
9
+
10
+
11
+ # ---------------------------------------------------------------------------
12
+ # haversine_miles
13
+ # ---------------------------------------------------------------------------
14
+
15
+ class TestHaversineMiles:
16
+ def test_same_point_is_zero(self):
17
+ assert haversine_miles(42.0, -71.0, 42.0, -71.0) == 0.0
18
+
19
+ def test_known_distance_boston_nyc(self):
20
+ # Boston (42.3601, -71.0589) to NYC (40.7128, -74.0060) ≈ 190 miles
21
+ dist = haversine_miles(42.3601, -71.0589, 40.7128, -74.0060)
22
+ assert 185 < dist < 195
23
+
24
+ def test_symmetry(self):
25
+ d1 = haversine_miles(42.0, -71.0, 34.0, -118.0)
26
+ d2 = haversine_miles(34.0, -118.0, 42.0, -71.0)
27
+ assert math.isclose(d1, d2, rel_tol=1e-9)
28
+
29
+ def test_short_distance(self):
30
+ # Two points ~1 mile apart
31
+ dist = haversine_miles(42.3370, -71.1061, 42.3514, -71.1061)
32
+ assert 0.8 < dist < 1.2
33
+
34
+ def test_returns_float(self):
35
+ result = haversine_miles(0.0, 0.0, 0.0, 1.0)
36
+ assert isinstance(result, float)
37
+
38
+
39
+ # ---------------------------------------------------------------------------
40
+ # PatientProfile.summary
41
+ # ---------------------------------------------------------------------------
42
+
43
+ class TestPatientProfileSummary:
44
+ def test_summary_contains_disease(self, als_patient):
45
+ assert "Amyotrophic Lateral Sclerosis" in als_patient.summary()
46
+
47
+ def test_summary_contains_age(self, als_patient):
48
+ assert "52" in als_patient.summary()
49
+
50
+ def test_summary_contains_onset_months(self, als_patient):
51
+ assert "18" in als_patient.summary()
52
+
53
+ def test_summary_contains_diagnosis_months(self, als_patient):
54
+ assert "12" in als_patient.summary()
55
+
56
+ def test_summary_contains_zip(self, als_patient):
57
+ assert "02115" in als_patient.summary()
58
+
59
+ def test_summary_contains_radius(self, als_patient):
60
+ assert "100" in als_patient.summary()
61
+
62
+ def test_summary_contains_benchmarks(self, als_patient):
63
+ text = als_patient.summary()
64
+ assert "alsfrs_r" in text
65
+ assert "38" in text
66
+
67
+ def test_summary_no_benchmarks(self):
68
+ patient = PatientProfile(
69
+ disease="ALS", age=45, onset_months=6,
70
+ zip_code="10001", lat=40.75, lon=-73.99,
71
+ )
72
+ assert "Benchmarks" not in patient.summary()
73
+
74
+ def test_summary_phase_labels(self):
75
+ patient = PatientProfile(
76
+ disease="ALS", age=45, onset_months=6,
77
+ zip_code="10001", lat=40.75, lon=-73.99,
78
+ phases=["2", "3", "0", "na"],
79
+ )
80
+ text = patient.summary()
81
+ assert "Phase 2" in text
82
+ assert "Phase 3" in text
83
+ assert "Early Phase 1" in text
84
+ assert "Not Applicable" in text
85
+
86
+ def test_summary_study_type_defaults(self):
87
+ patient = PatientProfile(
88
+ disease="ALS", age=45, onset_months=6,
89
+ zip_code="10001", lat=40.75, lon=-73.99,
90
+ )
91
+ text = patient.summary()
92
+ assert "Clinical trials" in text
93
+ assert "Observational" not in text
94
+ assert "EAP" not in text
95
+
96
+ def test_summary_include_observational(self):
97
+ patient = PatientProfile(
98
+ disease="ALS", age=45, onset_months=6,
99
+ zip_code="10001", lat=40.75, lon=-73.99,
100
+ include_observational=True,
101
+ )
102
+ assert "Observational" in patient.summary()
103
+
104
+ def test_summary_include_eap(self):
105
+ patient = PatientProfile(
106
+ disease="ALS", age=45, onset_months=6,
107
+ zip_code="10001", lat=40.75, lon=-73.99,
108
+ include_eap=True,
109
+ )
110
+ assert "EAP" in patient.summary()
111
+
112
+ def test_summary_returns_string(self, als_patient):
113
+ assert isinstance(als_patient.summary(), str)
114
+
115
+ def test_summary_no_phases(self):
116
+ patient = PatientProfile(
117
+ disease="ALS", age=45, onset_months=6,
118
+ zip_code="10001", lat=40.75, lon=-73.99,
119
+ )
120
+ assert "Phases:" not in patient.summary()
tests/test_prompts.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Tests for prompts.py — lookup_disease_profile function."""
2
+ from __future__ import annotations
3
+
4
+ import pytest
5
+
6
+ from prompts import lookup_disease_profile
7
+
8
+
9
+ class TestLookupDiseaseProfile:
10
+ # --- exact full_name matches ---
11
+
12
+ def test_exact_full_name(self):
13
+ result = lookup_disease_profile("Amyotrophic Lateral Sclerosis")
14
+ assert result is not None
15
+ assert result["id"] == "als"
16
+
17
+ def test_case_insensitive_full_name(self):
18
+ result = lookup_disease_profile("amyotrophic lateral sclerosis")
19
+ assert result is not None
20
+ assert result["id"] == "als"
21
+
22
+ def test_mixed_case_full_name(self):
23
+ result = lookup_disease_profile("AMYOTROPHIC LATERAL SCLEROSIS")
24
+ assert result is not None
25
+ assert result["id"] == "als"
26
+
27
+ # --- synonym matches ---
28
+
29
+ def test_synonym_als(self):
30
+ result = lookup_disease_profile("ALS")
31
+ assert result is not None
32
+ assert result["id"] == "als"
33
+
34
+ def test_synonym_lou_gehrig(self):
35
+ result = lookup_disease_profile("Lou Gehrig's disease")
36
+ assert result is not None
37
+ assert result["id"] == "als"
38
+
39
+ def test_synonym_mnd(self):
40
+ result = lookup_disease_profile("motor neuron disease")
41
+ assert result is not None
42
+ assert result["id"] == "als"
43
+
44
+ # --- other diseases in registry ---
45
+
46
+ def test_huntingtons_exact(self):
47
+ result = lookup_disease_profile("Huntington's Disease")
48
+ assert result is not None
49
+ assert result["id"] == "huntingtons"
50
+
51
+ def test_parkinsons_exact(self):
52
+ result = lookup_disease_profile("Parkinson's Disease")
53
+ assert result is not None
54
+ assert result["id"] == "parkinsons"
55
+
56
+ def test_sma_synonym(self):
57
+ result = lookup_disease_profile("SMA")
58
+ assert result is not None
59
+ assert result["id"] == "sma"
60
+
61
+ # --- partial containment fallback ---
62
+
63
+ def test_partial_containment_als_in_longer_string(self):
64
+ result = lookup_disease_profile("ALS (Amyotrophic Lateral Sclerosis)")
65
+ assert result is not None
66
+ assert result["id"] == "als"
67
+
68
+ # --- unknown disease ---
69
+
70
+ def test_unknown_disease_returns_none(self):
71
+ assert lookup_disease_profile("Totally Unknown Rare Disease XYZ") is None
72
+
73
+ def test_truly_unknown_disease_returns_none(self):
74
+ # A name that shares no substring with any registered disease
75
+ assert lookup_disease_profile("xyzzy-9999-zqj-unknown") is None
76
+
77
+ # --- profile structure ---
78
+
79
+ def test_profile_has_required_keys(self):
80
+ result = lookup_disease_profile("Amyotrophic Lateral Sclerosis")
81
+ assert result is not None
82
+ assert "id" in result
83
+ assert "full_name" in result
84
+ assert "synonyms" in result
85
+ assert "benchmarks" in result
86
+
87
+ def test_benchmarks_is_list(self):
88
+ result = lookup_disease_profile("Amyotrophic Lateral Sclerosis")
89
+ assert isinstance(result["benchmarks"], list)
90
+
91
+ def test_synonyms_is_list(self):
92
+ result = lookup_disease_profile("Amyotrophic Lateral Sclerosis")
93
+ assert isinstance(result["synonyms"], list)
94
+
95
+ def test_whitespace_stripped(self):
96
+ result = lookup_disease_profile(" Amyotrophic Lateral Sclerosis ")
97
+ assert result is not None
98
+ assert result["id"] == "als"