@@ -78,15 +78,31 @@ pub struct ProgressBarJsonFormatter;
78
78
impl ProgressBarJsonFormatter {
79
79
/// Get a json formatted string given the progress bar status
80
80
pub fn format ( progress_bar : & ProgressBar ) -> String {
81
- format ! (
82
- r#"{{"timestamp": "{}", "bytes_downloaded": {}, "bytes_total": {}, "seconds_left": {}.{:0>3}, "seconds_elapsed": {}.{:0>3}}}"# ,
81
+ ProgressBarJsonFormatter :: format_values (
83
82
Utc :: now ( ) . to_rfc3339 ( ) ,
84
83
progress_bar. position ( ) ,
85
84
progress_bar. length ( ) . unwrap_or ( 0 ) ,
86
- progress_bar. eta( ) . as_secs( ) ,
87
- progress_bar. eta( ) . subsec_millis( ) ,
88
- progress_bar. elapsed( ) . as_secs( ) ,
89
- progress_bar. elapsed( ) . subsec_millis( ) ,
85
+ progress_bar. eta ( ) ,
86
+ progress_bar. elapsed ( ) ,
87
+ )
88
+ }
89
+
90
+ fn format_values (
91
+ timestamp : String ,
92
+ bytes_downloaded : u64 ,
93
+ bytes_total : u64 ,
94
+ duration_left : Duration ,
95
+ duration_elapsed : Duration ,
96
+ ) -> String {
97
+ format ! (
98
+ r#"{{"timestamp": "{}", "bytes_downloaded": {}, "bytes_total": {}, "seconds_left": {}.{:0>3}, "seconds_elapsed": {}.{:0>3}}}"# ,
99
+ timestamp,
100
+ bytes_downloaded,
101
+ bytes_total,
102
+ duration_left. as_secs( ) ,
103
+ duration_left. subsec_millis( ) ,
104
+ duration_elapsed. as_secs( ) ,
105
+ duration_elapsed. subsec_millis( ) ,
90
106
)
91
107
}
92
108
}
@@ -150,13 +166,23 @@ mod tests {
150
166
151
167
use super :: * ;
152
168
use indicatif:: ProgressBar ;
169
+ use serde_json:: Value ;
153
170
154
171
#[ test]
155
- fn check_seconds_elapsed_in_json_report_with_more_than_100_milliseconds ( ) {
156
- let progress_bar = ProgressBar :: new ( 10 ) . with_elapsed ( Duration :: from_millis ( 5124 ) ) ;
157
-
158
- let json_string = ProgressBarJsonFormatter :: format ( & progress_bar) ;
172
+ fn check_seconds_formatting_in_json_report_with_more_than_100_milliseconds ( ) {
173
+ let json_string = ProgressBarJsonFormatter :: format_values (
174
+ "" . to_string ( ) ,
175
+ 0 ,
176
+ 0 ,
177
+ Duration :: from_millis ( 7569 ) ,
178
+ Duration :: from_millis ( 5124 ) ,
179
+ ) ;
159
180
181
+ assert ! (
182
+ json_string. contains( r#""seconds_left": 7.569"# ) ,
183
+ "Not expected value in json output: {}" ,
184
+ json_string
185
+ ) ;
160
186
assert ! (
161
187
json_string. contains( r#""seconds_elapsed": 5.124"# ) ,
162
188
"Not expected value in json output: {}" ,
@@ -165,11 +191,20 @@ mod tests {
165
191
}
166
192
167
193
#[ test]
168
- fn check_seconds_elapsed_in_json_report_with_less_than_100_milliseconds ( ) {
169
- let progress_bar = ProgressBar :: new ( 10 ) . with_elapsed ( Duration :: from_millis ( 5004 ) ) ;
170
-
171
- let json_string = ProgressBarJsonFormatter :: format ( & progress_bar) ;
194
+ fn check_seconds_formatting_in_json_report_with_less_than_100_milliseconds ( ) {
195
+ let json_string = ProgressBarJsonFormatter :: format_values (
196
+ "" . to_string ( ) ,
197
+ 0 ,
198
+ 0 ,
199
+ Duration :: from_millis ( 7006 ) ,
200
+ Duration :: from_millis ( 5004 ) ,
201
+ ) ;
172
202
203
+ assert ! (
204
+ json_string. contains( r#""seconds_left": 7.006"# ) ,
205
+ "Not expected value in json output: {}" ,
206
+ json_string
207
+ ) ;
173
208
assert ! (
174
209
json_string. contains( r#""seconds_elapsed": 5.004"# ) ,
175
210
"Not expected value in json output: {}" ,
@@ -178,40 +213,83 @@ mod tests {
178
213
}
179
214
180
215
#[ test]
181
- fn check_seconds_left_in_json_report_with_more_than_100_milliseconds ( ) {
182
- let half_position = 5 ;
183
- let progress_bar = ProgressBar :: new ( half_position * 2 ) ;
184
- sleep ( Duration :: from_millis ( 123 ) ) ;
185
- progress_bar. set_position ( half_position) ;
186
- let json_string = ProgressBarJsonFormatter :: format ( & progress_bar) ;
216
+ fn check_seconds_formatting_in_json_report_with_milliseconds_ending_by_zeros ( ) {
217
+ let json_string = ProgressBarJsonFormatter :: format_values (
218
+ "" . to_string ( ) ,
219
+ 0 ,
220
+ 0 ,
221
+ Duration :: from_millis ( 7200 ) ,
222
+ Duration :: from_millis ( 5100 ) ,
223
+ ) ;
187
224
188
- let milliseconds = progress_bar. eta ( ) . subsec_millis ( ) ;
189
- assert ! ( milliseconds > 100 ) ;
190
225
assert ! (
191
- json_string. contains( & format!( r#""seconds_left": 0.{}"# , milliseconds) ) ,
226
+ json_string. contains( r#""seconds_left": 7.200"# ) ,
227
+ "Not expected value in json output: {}" ,
228
+ json_string
229
+ ) ;
230
+ assert ! (
231
+ json_string. contains( r#""seconds_elapsed": 5.100"# ) ,
192
232
"Not expected value in json output: {}" ,
193
233
json_string
194
234
) ;
195
235
}
196
236
197
237
#[ test]
198
- fn check_seconds_left_in_json_report_with_less_than_100_milliseconds ( ) {
199
- let half_position = 5 ;
200
- let progress_bar = ProgressBar :: new ( half_position * 2 ) ;
201
- sleep ( Duration :: from_millis ( 1 ) ) ;
202
- progress_bar. set_position ( half_position) ;
238
+ fn check_seconds_left_and_elapsed_time_are_used_by_the_formatter ( ) {
239
+ fn format_duration ( duration : & Duration ) -> String {
240
+ format ! ( "{}.{}" , duration. as_secs( ) , duration. subsec_nanos( ) )
241
+ }
242
+ fn round_at_ms ( duration : Duration ) -> Duration {
243
+ Duration :: from_millis ( duration. as_millis ( ) as u64 )
244
+ }
245
+
246
+ // 4 steps
247
+ let progress_bar = ProgressBar :: new ( 4 ) ;
248
+ // 1 step done in 15 ms, left 45ms to finish the 4th steps
249
+ sleep ( Duration :: from_millis ( 15 ) ) ;
250
+ progress_bar. set_position ( 1 ) ;
251
+
252
+ let duration_left_before = round_at_ms ( progress_bar. eta ( ) ) ;
253
+ let duration_elapsed_before = round_at_ms ( progress_bar. elapsed ( ) ) ;
254
+
203
255
let json_string = ProgressBarJsonFormatter :: format ( & progress_bar) ;
204
256
257
+ let duration_left_after = round_at_ms ( progress_bar. eta ( ) ) ;
258
+ let duration_elapsed_after = round_at_ms ( progress_bar. elapsed ( ) ) ;
259
+
260
+ // Milliseconds in json may not be exactly the same as the one we get because of the test duration.
261
+ let delta = 0.1 ;
262
+
263
+ let json_value: Value = serde_json:: from_str ( & json_string) . unwrap ( ) ;
264
+ let seconds_left = json_value[ "seconds_left" ] . as_f64 ( ) . unwrap ( ) ;
265
+ let seconds_elapsed = json_value[ "seconds_elapsed" ] . as_f64 ( ) . unwrap ( ) ;
266
+
267
+ // We check that we pass the right values to format checking that time left is 3 times the time elapsed
205
268
assert ! (
206
- json_string. contains( r#""seconds_left": 0.0"# ) ,
207
- "Not expected value in json output: {}" ,
208
- json_string
269
+ seconds_elapsed * 3.0 - delta < seconds_left
270
+ && seconds_left < seconds_elapsed * 3.0 + delta,
271
+ "seconds_left should be close to 3*{} but it's {}." ,
272
+ & seconds_elapsed,
273
+ & seconds_left
209
274
) ;
210
275
276
+ let duration_left = Duration :: from_secs_f64 ( seconds_left) ;
211
277
assert ! (
212
- !json_string. contains( r#""seconds_left": 0.000"# ) ,
213
- "Not expected value in json output: {}" ,
214
- json_string
278
+ duration_left_before <= duration_left && duration_left <= duration_left_after,
279
+ "Duration left: {} should be between {} and {}" ,
280
+ format_duration( & duration_left) ,
281
+ format_duration( & duration_left_before) ,
282
+ format_duration( & duration_left_after) ,
283
+ ) ;
284
+
285
+ let duration_elapsed = Duration :: from_secs_f64 ( seconds_elapsed) ;
286
+ assert ! (
287
+ duration_elapsed_before <= duration_elapsed
288
+ && duration_elapsed <= duration_elapsed_after,
289
+ "Duration elapsed: {} should be between {} and {}" ,
290
+ format_duration( & duration_elapsed) ,
291
+ format_duration( & duration_elapsed_before) ,
292
+ format_duration( & duration_elapsed_after) ,
215
293
) ;
216
294
}
217
295
}
0 commit comments