@@ -327,6 +327,10 @@ impl ComparisonSummary {
327
327
. count ( )
328
328
}
329
329
330
+ pub fn is_empty ( & self ) -> bool {
331
+ self . comparisons . is_empty ( )
332
+ }
333
+
330
334
fn arithmetic_mean < ' a > (
331
335
& ' a self ,
332
336
changes : impl Iterator < Item = & ' a TestResultComparison > ,
@@ -473,7 +477,7 @@ pub fn write_summary_table(
473
477
474
478
writeln ! (
475
479
result,
476
- "| mean[^2] | {} | {} | {} | {} | {:.1}% |" ,
480
+ "| mean[^2] | {} | {} | {} | {} | {} |" ,
477
481
render_stat( primary. num_regressions, || Some (
478
482
primary. arithmetic_mean_of_regressions( )
479
483
) ) ,
@@ -486,21 +490,30 @@ pub fn write_summary_table(
486
490
render_stat( secondary. num_improvements, || Some (
487
491
secondary. arithmetic_mean_of_improvements( )
488
492
) ) ,
489
- primary. arithmetic_mean_of_changes( )
493
+ if primary. is_empty( ) {
494
+ "N/A" . to_string( )
495
+ } else {
496
+ format!( "{:.1}%" , primary. arithmetic_mean_of_changes( ) )
497
+ }
490
498
)
491
499
. unwrap ( ) ;
492
500
493
- let largest_change = primary
494
- . most_relevant_changes ( )
495
- . iter ( )
496
- . fold ( 0.0 , |accum : f64 , item| {
497
- let change = item. map ( |v| v. relative_change ( ) * 100.0 ) . unwrap_or ( 0.0 ) ;
498
- accum. max ( change)
499
- } ) ;
501
+ let largest_change = if primary. is_empty ( ) {
502
+ "N/A" . to_string ( )
503
+ } else {
504
+ let change = primary
505
+ . most_relevant_changes ( )
506
+ . iter ( )
507
+ . fold ( 0.0 , |accum : f64 , item| {
508
+ let change = item. map ( |v| v. relative_change ( ) * 100.0 ) . unwrap_or ( 0.0 ) ;
509
+ accum. max ( change)
510
+ } ) ;
511
+ format ! ( "{:.1}%" , change)
512
+ } ;
500
513
501
514
writeln ! (
502
515
result,
503
- "| max | {} | {} | {} | {} | {:.1}% |" ,
516
+ "| max | {} | {} | {} | {} | {} |" ,
504
517
render_stat( primary. num_regressions, || primary
505
518
. largest_regression( )
506
519
. map( |r| r. relative_change( ) * 100.0 ) ) ,
@@ -1353,6 +1366,7 @@ fn compare_link(start: &ArtifactId, end: &ArtifactId) -> String {
1353
1366
1354
1367
#[ cfg( test) ]
1355
1368
mod tests {
1369
+ use collector:: category:: Category ;
1356
1370
use std:: collections:: HashSet ;
1357
1371
1358
1372
use database:: { ArtifactId , Profile , Scenario } ;
@@ -1363,12 +1377,12 @@ mod tests {
1363
1377
} ;
1364
1378
1365
1379
#[ test]
1366
- fn summary_table_only_improvements ( ) {
1380
+ fn summary_table_only_improvements_primary ( ) {
1367
1381
check_table (
1368
1382
vec ! [
1369
- ( "primary" , 5.0 , 10.0 ) ,
1370
- ( "primary" , 5.0 , 12.0 ) ,
1371
- ( "primary" , 1.0 , 3.0 ) ,
1383
+ ( Category :: Primary , 5.0 , 10.0 ) ,
1384
+ ( Category :: Primary , 5.0 , 12.0 ) ,
1385
+ ( Category :: Primary , 1.0 , 3.0 ) ,
1372
1386
] ,
1373
1387
r#"
1374
1388
| | Regressions 😿 <br />(primary) | Regressions 😿 <br />(secondary) | Improvements 🎉 <br />(primary) | Improvements 🎉 <br />(secondary) | All 😿 🎉 <br />(primary) |
@@ -1385,12 +1399,12 @@ mod tests {
1385
1399
}
1386
1400
1387
1401
#[ test]
1388
- fn summary_table_only_regressions ( ) {
1402
+ fn summary_table_only_regressions_primary ( ) {
1389
1403
check_table (
1390
1404
vec ! [
1391
- ( "primary" , 5.0 , 2.0 ) ,
1392
- ( "primary" , 5.0 , 1.0 ) ,
1393
- ( "primary" , 4.0 , 1.0 ) ,
1405
+ ( Category :: Primary , 5.0 , 2.0 ) ,
1406
+ ( Category :: Primary , 5.0 , 1.0 ) ,
1407
+ ( Category :: Primary , 4.0 , 1.0 ) ,
1394
1408
] ,
1395
1409
r#"
1396
1410
| | Regressions 😿 <br />(primary) | Regressions 😿 <br />(secondary) | Improvements 🎉 <br />(primary) | Improvements 🎉 <br />(secondary) | All 😿 🎉 <br />(primary) |
@@ -1406,14 +1420,58 @@ mod tests {
1406
1420
) ;
1407
1421
}
1408
1422
1423
+ #[ test]
1424
+ fn summary_table_only_improvements_secondary ( ) {
1425
+ check_table (
1426
+ vec ! [
1427
+ ( Category :: Secondary , 5.0 , 2.0 ) ,
1428
+ ( Category :: Secondary , 5.0 , 1.0 ) ,
1429
+ ( Category :: Secondary , 4.0 , 1.0 ) ,
1430
+ ] ,
1431
+ r#"
1432
+ | | Regressions 😿 <br />(primary) | Regressions 😿 <br />(secondary) | Improvements 🎉 <br />(primary) | Improvements 🎉 <br />(secondary) | All 😿 🎉 <br />(primary) |
1433
+ |:---:|:---:|:---:|:---:|:---:|:---:|
1434
+ | count[^1] | 0 | 0 | 0 | 3 | 0 |
1435
+ | mean[^2] | N/A | N/A | N/A | -71.7% | N/A |
1436
+ | max | N/A | N/A | N/A | -80.0% | N/A |
1437
+
1438
+ [^1]: *number of relevant changes*
1439
+ [^2]: *the arithmetic mean of the percent change*
1440
+ "#
1441
+ . trim_start ( ) ,
1442
+ ) ;
1443
+ }
1444
+
1445
+ #[ test]
1446
+ fn summary_table_only_regressions_secondary ( ) {
1447
+ check_table (
1448
+ vec ! [
1449
+ ( Category :: Secondary , 5.0 , 10.0 ) ,
1450
+ ( Category :: Secondary , 5.0 , 12.0 ) ,
1451
+ ( Category :: Secondary , 1.0 , 3.0 ) ,
1452
+ ] ,
1453
+ r#"
1454
+ | | Regressions 😿 <br />(primary) | Regressions 😿 <br />(secondary) | Improvements 🎉 <br />(primary) | Improvements 🎉 <br />(secondary) | All 😿 🎉 <br />(primary) |
1455
+ |:---:|:---:|:---:|:---:|:---:|:---:|
1456
+ | count[^1] | 0 | 3 | 0 | 0 | 0 |
1457
+ | mean[^2] | N/A | 146.7% | N/A | N/A | N/A |
1458
+ | max | N/A | 200.0% | N/A | N/A | N/A |
1459
+
1460
+ [^1]: *number of relevant changes*
1461
+ [^2]: *the arithmetic mean of the percent change*
1462
+ "#
1463
+ . trim_start ( ) ,
1464
+ ) ;
1465
+ }
1466
+
1409
1467
#[ test]
1410
1468
fn summary_table_mixed_primary ( ) {
1411
1469
check_table (
1412
1470
vec ! [
1413
- ( "primary" , 10.0 , 5.0 ) ,
1414
- ( "primary" , 5.0 , 10.0 ) ,
1415
- ( "primary" , 1.0 , 3.0 ) ,
1416
- ( "primary" , 4.0 , 1.0 ) ,
1471
+ ( Category :: Primary , 10.0 , 5.0 ) ,
1472
+ ( Category :: Primary , 5.0 , 10.0 ) ,
1473
+ ( Category :: Primary , 1.0 , 3.0 ) ,
1474
+ ( Category :: Primary , 4.0 , 1.0 ) ,
1417
1475
] ,
1418
1476
r#"
1419
1477
| | Regressions 😿 <br />(primary) | Regressions 😿 <br />(secondary) | Improvements 🎉 <br />(primary) | Improvements 🎉 <br />(secondary) | All 😿 🎉 <br />(primary) |
@@ -1433,12 +1491,12 @@ mod tests {
1433
1491
fn summary_table_mixed_primary_secondary ( ) {
1434
1492
check_table (
1435
1493
vec ! [
1436
- ( "primary" , 10.0 , 5.0 ) ,
1437
- ( "primary" , 5.0 , 10.0 ) ,
1438
- ( "secondary" , 5.0 , 10.0 ) ,
1439
- ( "primary" , 1.0 , 3.0 ) ,
1440
- ( "secondary" , 3.0 , 1.0 ) ,
1441
- ( "primary" , 4.0 , 1.0 ) ,
1494
+ ( Category :: Primary , 10.0 , 5.0 ) ,
1495
+ ( Category :: Primary , 5.0 , 10.0 ) ,
1496
+ ( Category :: Secondary , 5.0 , 10.0 ) ,
1497
+ ( Category :: Primary , 1.0 , 3.0 ) ,
1498
+ ( Category :: Secondary , 3.0 , 1.0 ) ,
1499
+ ( Category :: Primary , 4.0 , 1.0 ) ,
1442
1500
] ,
1443
1501
r#"
1444
1502
| | Regressions 😿 <br />(primary) | Regressions 😿 <br />(secondary) | Improvements 🎉 <br />(primary) | Improvements 🎉 <br />(secondary) | All 😿 🎉 <br />(primary) |
@@ -1455,11 +1513,11 @@ mod tests {
1455
1513
}
1456
1514
1457
1515
// (category, before, after)
1458
- fn check_table ( values : Vec < ( & str , f64 , f64 ) > , expected : & str ) {
1516
+ fn check_table ( values : Vec < ( Category , f64 , f64 ) > , expected : & str ) {
1459
1517
let mut primary_statistics = HashSet :: new ( ) ;
1460
1518
let mut secondary_statistics = HashSet :: new ( ) ;
1461
1519
for ( index, ( category, before, after) ) in values. into_iter ( ) . enumerate ( ) {
1462
- let target = if category == "primary" {
1520
+ let target = if category == Category :: Primary {
1463
1521
& mut primary_statistics
1464
1522
} else {
1465
1523
& mut secondary_statistics
0 commit comments