@@ -246,127 +246,117 @@ impl<T: Write> OutputFormatter for HumanFormatter<T> {
246
246
}
247
247
248
248
pub ( crate ) struct JsonFormatter < T > {
249
- out : OutputLocation < T > ,
250
- had_events : bool
249
+ out : OutputLocation < T >
251
250
}
252
251
253
252
impl < T : Write > JsonFormatter < T > {
254
253
pub fn new ( out : OutputLocation < T > ) -> Self {
255
254
Self {
256
- out,
257
- had_events : false
258
- }
255
+ out, }
259
256
}
260
257
261
258
fn write_str < S : AsRef < str > > ( & mut self , s : S ) -> io:: Result < ( ) > {
262
- self . out . write_all ( s. as_ref ( ) . as_ref ( ) )
259
+ self . out . write_all ( s. as_ref ( ) . as_ref ( ) ) ?;
260
+ self . out . write_all ( "\n " . as_ref ( ) )
263
261
}
262
+ }
264
263
265
- fn write_event ( & mut self , event : & str ) -> io:: Result < ( ) > {
266
- if self . had_events {
267
- self . out . write_all ( b",\n " ) ?;
268
- }
269
- else {
270
- self . had_events = true ;
271
- }
272
-
273
- self . out . write_all ( event. as_ref ( ) )
274
- }
264
+ fn naive_json_escape ( input : & str ) -> String {
265
+ input. replace ( "\\ " , "\\ \\ " ) . replace ( "\" " , "\\ \" " )
275
266
}
276
267
277
268
impl < T : Write > OutputFormatter for JsonFormatter < T > {
278
- fn write_run_start ( & mut self , _len : usize ) -> io:: Result < ( ) > {
279
- self . write_str ( "{\n \t events: [\n " )
269
+ fn write_run_start ( & mut self , len : usize ) -> io:: Result < ( ) > {
270
+ self . write_str (
271
+ & * format ! ( r#"{{ "type": "suite", "event": "started", "test_count": "{}" }}"# , len) )
280
272
}
281
273
282
274
fn write_test_start ( & mut self ,
283
275
desc : & TestDesc ,
284
276
_align : NamePadding ,
285
277
_max_name_len : usize ) -> io:: Result < ( ) > {
286
- self . write_event ( & * format ! ( "\t \t {{ \" test\" : \" {}\" , \" event\" : \" started\" }}" , desc. name) )
278
+ self . write_str ( & * format ! ( r#"{{ "type": "test", "event": "started", "name": "{}" }}"# ,
279
+ desc. name) )
287
280
}
288
281
289
282
fn write_result ( & mut self , desc : & TestDesc , result : & TestResult ) -> io:: Result < ( ) > {
290
283
let output = match * result {
291
284
TrOk => {
292
- format ! ( "\t \t {{ \" test\" : \" {}\" , \" event\" : \" ok\" }}" , desc. name)
285
+ format ! ( r#"{{ "type": "test", "event": "ok", "name": "{}" }}"# ,
286
+ desc. name)
293
287
} ,
294
288
295
289
TrFailed => {
296
- format ! ( "\t \t {{ \" test\" : \" {}\" , \" event\" : \" failed\" }}" , desc. name)
290
+ format ! ( r#"{{ "type": "test", "event": "failed", "name": "{}" }}"# ,
291
+ desc. name)
297
292
} ,
298
293
299
294
TrFailedMsg ( ref m) => {
300
- format ! ( " \t \t {{ \" test \ " : \" {} \ " , \ " event\ " : \ " failed\ " , \" extra \ " : \ " {}\" }}" ,
295
+ format ! ( r#" {{ "type ": "test ", "event": "failed", "name ": "{}", "message": "{}" }}"# ,
301
296
desc. name,
302
- m )
297
+ naive_json_escape ( m ) )
303
298
} ,
304
299
305
300
TrIgnored => {
306
- format ! ( "\t \t {{ \" test\" : \" {}\" , \" event\" : \" ignored\" }}" , desc. name)
301
+ format ! ( r#"{{ "type": "test", "event": "ignored", "name": "{}" }}"# ,
302
+ desc. name)
307
303
} ,
308
304
309
305
TrAllowedFail => {
310
- format ! ( "\t \t {{ \" test\" : \" {}\" , \" event\" : \" allowed_failure\" }}" , desc. name)
306
+ format ! ( r#"{{ "type": "test", "event": "allowed_failure", "name": "{}" }}"# ,
307
+ desc. name)
311
308
} ,
312
309
313
310
TrMetrics ( ref mm) => {
314
- format ! ( " \t \t {{ \" test \ " : \" {} \ " , \" event \ " : \" metrics \ " , \" extra \ " : \ " {}\ " }}",
311
+ format ! ( r#" {{ "type ": "metrics ", "name ": "{} ", "metrics ": "{}" }}"# ,
315
312
desc. name,
316
313
mm. fmt_metrics( ) )
317
314
} ,
318
315
319
316
TrBench ( ref bs) => {
320
- format ! ( " \t \t {{ \" test \ " : \" {} \ " , \" event \ " : \" bench \ " , \" extra \ " : \ " {}\ " }}",
317
+ format ! ( r#" {{ "type ": "bench ", "name ": "{} ", "bench ": "{}" }}"# ,
321
318
desc. name,
322
319
fmt_bench_samples( bs) )
323
320
} ,
324
321
} ;
325
322
326
- self . write_event ( & * output)
323
+ self . write_str ( & * output)
327
324
}
328
325
329
326
fn write_timeout ( & mut self , desc : & TestDesc ) -> io:: Result < ( ) > {
330
- self . write_event ( & * format ! ( "\t {{ \" test\" : \" {}\" , \" event\" : \" timeout\" }}" , desc. name) )
327
+ self . write_str ( & * format ! ( r#"{{ "type": "test", "event": "timeout", "name": "{}" }}"# ,
328
+ desc. name) )
331
329
}
332
330
333
331
fn write_run_finish ( & mut self , state : & ConsoleTestState ) -> io:: Result < bool > {
334
- self . write_str ( "\n \t ],\n \t \" summary\" : {\n " ) ?;
335
332
336
- self . write_str ( & * format ! ( "\t \t \" passed\" : {},\n " , state. passed) ) ?;
337
- self . write_str ( & * format ! ( "\t \t \" failed\" : {},\n " , state. failed + state. allowed_fail) ) ?;
338
- self . write_str ( & * format ! ( "\t \t \" allowed_fail\" : {},\n " , state. allowed_fail) ) ?;
339
- self . write_str ( & * format ! ( "\t \t \" ignored\" : {},\n " , state. ignored) ) ?;
340
- self . write_str ( & * format ! ( "\t \t \" measured\" : {},\n " , state. measured) ) ?;
333
+ self . write_str ( & * format ! ( r#"{{ "type": "suite",
334
+ "event": "{}",
335
+ "passed": {},
336
+ "failed": {},
337
+ "allowed_fail": {},
338
+ "ignored": {},
339
+ "measured": {},
340
+ "filtered_out": "{}" }}"# ,
341
+ if state. failed == 0 { "ok" } else { "failed" } ,
342
+ state. passed,
343
+ state. failed + state. allowed_fail,
344
+ state. allowed_fail,
345
+ state. ignored,
346
+ state. measured,
347
+ state. filtered_out) ) ?;
341
348
342
- if state. failed == 0 {
343
- self . write_str ( & * format ! ( "\t \t \" filtered_out\" : {}\n " , state. filtered_out) ) ?;
344
- } else {
345
- self . write_str ( & * format ! ( "\t \t \" filtered_out\" : {},\n " , state. filtered_out) ) ?;
346
- self . write_str ( "\t \t \" failures\" : [\n " ) ?;
347
-
348
- let mut has_items = false ;
349
- for & ( ref f, ref stdout) in & state. failures {
350
- if !stdout. is_empty ( ) {
351
- if has_items {
352
- self . write_str ( ",\n " ) ?;
353
- } else {
354
- has_items = true ;
355
- }
356
-
357
- let output = String :: from_utf8_lossy ( stdout)
358
- . replace ( "\\ " , "\\ \\ " )
359
- . replace ( "\" " , "\\ \" " ) ;
360
-
361
- self . write_str ( & * format ! ( "\t \t \t \" {}\" : \" {}\" " , f. name, output) ) ?;
362
- }
363
- }
349
+ for & ( ref f, ref stdout) in & state. failures {
350
+ if !stdout. is_empty ( ) {
351
+ let output = naive_json_escape ( & * String :: from_utf8_lossy ( stdout) ) ;
364
352
365
- self . write_str ( "\n \t \t ]\n " ) ?;
353
+ self . write_str (
354
+ & * format ! ( r#"{{ "type": "test_output", "name": "{}" "output": "{}" }}"# ,
355
+ f. name,
356
+ output) ) ?;
357
+ }
366
358
}
367
359
368
- self . write_str ( "\t }\n }\n " ) ?;
369
-
370
360
Ok ( state. failed == 0 )
371
361
}
372
362
}
0 commit comments