1+ import pytest
2+
3+ import penn_chime .cli
4+
5+ from datetime import date , timedelta
6+
7+ def test_main_with_doubling_time ():
8+ """"
9+ Tests a run via CLI with the minimum amount of parameters. Exponential
10+ factor is defined by doubling-time.
11+ """
12+ arguments = [
13+ "pytest" ,
14+ "--current-hospitalized" , "1" ,
15+ "--doubling-time" , "2.5" ,
16+ "--hospitalized-days" , "5" ,
17+ "--hospitalized-rate" , "0.01" ,
18+ "--icu-days" , "10" ,
19+ "--icu-rate" , "0.5" ,
20+ "--market-share" , "0.1" ,
21+ "--infectious-days" , "5" ,
22+ "--max-y-axis" , "10000" ,
23+ "--n-days" , "200" ,
24+ "--recovered" , "10" ,
25+ "--relative-contact-rate" , "0.1" ,
26+ "--population" , "1000000" ,
27+ "--ventilated-days" , "5" ,
28+ "--ventilated-rate" , "0.025"
29+ ]
30+
31+ penn_chime .cli .run (arguments )
32+
33+ def test_main_with_date_first_hospitalized ():
34+ """"
35+ Tests a run via CLI with the minimum amount of parameters. Exponential
36+ factor is defined by date-first-hospitalized.
37+ """
38+ arguments = [
39+ "pytest" ,
40+ "--current-hospitalized" , "69" ,
41+ "--current-date" , "2020-04-14" ,
42+ "--date-first-hospitalized" , "2020-04-01" ,
43+ "--hospitalized-days" , "5" ,
44+ "--hospitalized-rate" , "0.025" ,
45+ "--icu-days" , "9" ,
46+ "--icu-rate" , "0.075" ,
47+ "--market-share" , "0.1" ,
48+ "--infectious-days" , "14" ,
49+ "--max-y-axis" , "1000" ,
50+ "--n-days" , "30" ,
51+ "--recovered" , "0" ,
52+ "--relative-contact-rate" , "0.1" ,
53+ "--population" , "1000000" ,
54+ "--ventilated-days" , "10" ,
55+ "--ventilated-rate" , "0.005"
56+ ]
57+
58+ penn_chime .cli .run (arguments )
59+
60+ def test_failure_on_missing_parameters ():
61+ """Negative test to verify that an error is given when neither defining
62+ doubling-time nor date-first-hospitalized."""
63+ arguments = [
64+ "pytest" ,
65+ "--current-hospitalized" , "69" ,
66+ "--hospitalized-days" , "5" ,
67+ "--hospitalized-rate" , "0.025" ,
68+ "--icu-days" , "9" ,
69+ "--icu-rate" , "0.075" ,
70+ "--market-share" , "0.1" ,
71+ "--infectious-days" , "14" ,
72+ "--max-y-axis" , "1000" ,
73+ "--n-days" , "30" ,
74+ "--recovered" , "0" ,
75+ "--relative-contact-rate" , "0.1" ,
76+ "--population" , "1000000" ,
77+ "--ventilated-days" , "10" ,
78+ "--ventilated-rate" , "0.005"
79+ ]
80+
81+ with pytest .raises (AssertionError ):
82+ penn_chime .cli .run (arguments )
83+
84+ def test_main_with_csv_verification ():
85+ """Integration test for CLI. Runs a five-day simulation and verifies the
86+ content of the resulting csv files."""
87+ current_date = date .today ().strftime ("%Y-%m-%d" )
88+ n_days = 5
89+ arguments = [
90+ "pytest" ,
91+ "--current-hospitalized" , "1" ,
92+ "--current-date" , current_date ,
93+ "--doubling-time" , "2.5" ,
94+ "--hospitalized-days" , "5" ,
95+ "--hospitalized-rate" , "0.01" ,
96+ "--icu-days" , "10" ,
97+ "--icu-rate" , "0.5" ,
98+ "--market-share" , "0.1" ,
99+ "--infectious-days" , "5" ,
100+ "--max-y-axis" , "10000" ,
101+ "--n-days" , str (n_days ),
102+ "--recovered" , "10" ,
103+ "--relative-contact-rate" , "0.1" ,
104+ "--population" , "1000000" ,
105+ "--ventilated-days" , "5" ,
106+ "--ventilated-rate" , "0.025"
107+ ]
108+
109+ penn_chime .cli .run (arguments )
110+
111+ #Verify content of projected_admits.csv
112+ projected_admits_content = [
113+ [None , None , None ],
114+ [0.5195079107728944 ,25.97539553864472 ,1.298769776932236 ],
115+ [0.6851383215271454 ,34.25691607635727 ,1.7128458038178636 ],
116+ [0.8129161146846768 ,40.64580573423383 ,2.0322902867116914 ],
117+ [1.029120162473117 ,51.456008123655835 ,2.5728004061827923 ],
118+ [1.3021513067257287 ,65.10756533628646 ,3.255378266814322 ],
119+ [1.6465388184586223 ,82.32694092293116 ,4.116347046146558 ],
120+ [2.0802813033400414 ,104.01406516700195 ,5.200703258350099 ]
121+ ]
122+
123+ __validate_file (projected_admits_content , ",day,date,admits_hospitalized,admits_icu,admits_ventilated\n " , current_date + "_projected_admits.csv" )
124+
125+ #Verify content of projected_admits.csv
126+ projected_census_content = [
127+ [0.0 ,0.0 ,0.0 ],
128+ [0.5195079107728944 ,25.97539553864472 ,1.298769776932236 ],
129+ [1.2046462323000398 ,60.23231161500199 ,3.0116155807500995 ],
130+ [2.0175623469847164 ,100.87811734923582 ,5.043905867461791 ],
131+ [3.0466825094578334 ,152.33412547289166 ,7.616706273644583 ],
132+ [4.3488338161835625 ,217.4416908091781 ,10.872084540458905 ],
133+ [5.47586472386929 ,299.76863173210927 ,13.689661809673227 ],
134+ [6.871007705682186 ,403.7826968991112 ,17.17751926420546 ]
135+ ]
136+
137+ __validate_file (projected_census_content , ",day,date,census_hospitalized,census_icu,census_ventilated\n " , current_date + "_projected_census.csv" )
138+
139+ #Verify content of sim_sir_w_date.csv
140+ sim_sir_w_date_content = [
141+ [999000.0 ,1000.0 ,10.0 ],
142+ [998480.4920892271 ,1319.5079107728943 ,210.0 ],
143+ [997795.3537677001 ,1740.7446501454608 ,473.901582154579 ],
144+ [996982.4376530153 ,2205.5118348010456 ,822.0505121836709 ],
145+ [995953.3174905422 ,2793.529630313953 ,1263.15287914388 ],
146+ [994651.1661838164 ,3536.9750109768916 ,1821.8588052066705 ],
147+ [993004.6273653577 ,4476.118827240136 ,2529.2538074020486 ],
148+ [990924.346062018 ,5661.176365132148 ,3424.4775728500767 ]
149+ ]
150+
151+ __validate_file (sim_sir_w_date_content , ",day,date,susceptible,infected,recovered\n " , current_date + "_sim_sir_w_date.csv" )
152+
153+
154+ def __validate_file (reference_file_content , reference_file_header , reference_file_name ):
155+ with open (reference_file_name , "r" ) as f :
156+ lines = f .readlines ()
157+ assert len (lines ) == len (reference_file_content ) + 1
158+ assert lines [0 ] == reference_file_header
159+
160+ for i , row in enumerate (lines [1 :]):
161+ reference_row = reference_file_content [i ]
162+ tokens = row .split ("," )
163+ row_date = date .today () + timedelta (days = i - 2 )
164+ assert int (tokens [0 ]) == i , f"Failed for file { reference_file_name } row { i + 1 } ."
165+ assert int (tokens [1 ]) == i - 2 , f"Failed for file { reference_file_name } row { i + 1 } ."
166+ assert tokens [2 ] == row_date .strftime ("%Y-%m-%d" ), f"Failed for file { reference_file_name } row { i + 1 } ."
167+ print (f"'{ tokens [3 ]} ,{ tokens [4 ]} ,{ tokens [5 ]} '" )
168+ assert not tokens [3 ].strip () or float (tokens [3 ]) == pytest .approx (reference_row [0 ], 1e-10 , 1e-1 ), f"Failed for file { reference_file_name } row { i + 1 } ."
169+ assert not tokens [4 ].strip () or float (tokens [4 ]) == pytest .approx (reference_row [1 ], 1e-10 , 1e-2 ), f"Failed for file { reference_file_name } row { i + 1 } ."
170+ assert not tokens [5 ].strip () or float (tokens [5 ]) == pytest .approx (reference_row [2 ], 1e-10 , 1e-3 ), f"Failed for file { reference_file_name } row { i + 1 } ."
171+
172+
173+
0 commit comments