@@ -60,19 +60,27 @@ fn gather_test_suites(job_metrics: &HashMap<JobName, JobMetrics>) -> TestSuites
6060
6161 for test in & suite. tests {
6262 let test_name = normalize_test_name ( & test. name , & suite_name) ;
63- let test_entry = suite_entry
64- . tests
65- . entry ( test_name. clone ( ) )
66- . or_insert_with ( || Test { name : test_name, passed : vec ! [ ] , ignored : vec ! [ ] } ) ;
63+ let ( test_name, variant_name) = match test_name. rsplit_once ( '#' ) {
64+ Some ( ( name, variant) ) => ( name. to_string ( ) , variant. to_string ( ) ) ,
65+ None => ( test_name, "" . to_string ( ) ) ,
66+ } ;
67+ let test_entry = suite_entry. tests . entry ( test_name. clone ( ) ) . or_insert_with ( || {
68+ Test { name : test_name. clone ( ) , revisions : Default :: default ( ) }
69+ } ) ;
70+ let variant_entry = test_entry
71+ . revisions
72+ . entry ( variant_name)
73+ . or_insert_with ( || TestResults { passed : vec ! [ ] , ignored : vec ! [ ] } ) ;
74+
6775 match test. outcome {
6876 TestOutcome :: Passed => {
69- test_entry . passed . push ( test_metadata) ;
77+ variant_entry . passed . push ( test_metadata) ;
7078 }
7179 TestOutcome :: Ignored { ignore_reason : _ } => {
72- test_entry . ignored . push ( test_metadata) ;
80+ variant_entry . ignored . push ( test_metadata) ;
7381 }
7482 TestOutcome :: Failed => {
75- eprintln ! ( "Warning: failed test" ) ;
83+ eprintln ! ( "Warning: failed test {test_name} " ) ;
7684 }
7785 }
7886 }
@@ -158,12 +166,29 @@ struct TestSuite<'a> {
158166}
159167
160168#[ derive( Debug , serde:: Serialize ) ]
161- struct Test < ' a > {
162- name : String ,
169+ struct TestResults < ' a > {
163170 passed : Vec < TestMetadata < ' a > > ,
164171 ignored : Vec < TestMetadata < ' a > > ,
165172}
166173
174+ #[ derive( Debug , serde:: Serialize ) ]
175+ struct Test < ' a > {
176+ name : String ,
177+ revisions : BTreeMap < String , TestResults < ' a > > ,
178+ }
179+
180+ impl < ' a > Test < ' a > {
181+ /// If this is a test without revisions, it will have a single entry in `revisions` with
182+ /// an empty string as the revision name.
183+ fn single_test ( & self ) -> Option < & TestResults < ' a > > {
184+ if self . revisions . len ( ) == 1 {
185+ self . revisions . iter ( ) . next ( ) . take_if ( |e| e. 0 . is_empty ( ) ) . map ( |e| e. 1 )
186+ } else {
187+ None
188+ }
189+ }
190+ }
191+
167192#[ derive( Clone , Copy , Debug , serde:: Serialize ) ]
168193struct TestMetadata < ' a > {
169194 job : & ' a str ,
0 commit comments