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