@@ -6,6 +6,7 @@ use quick_xml::de::from_reader;
66use serde:: Deserialize ;
77use std:: collections:: HashMap ;
88use std:: collections:: HashSet ;
9+ use std:: collections:: VecDeque ;
910use std:: fs:: canonicalize;
1011use std:: fs:: File ;
1112use std:: io:: BufReader ;
@@ -29,15 +30,59 @@ struct Opt {
2930}
3031
3132#[ derive( Debug , Deserialize , PartialEq ) ]
32- struct Testsuites {
33- #[ serde( rename = "testsuite" , default ) ]
34- testsuites : Vec < Testsuite > ,
33+ struct TestResultXml {
34+ #[ serde( rename = "testsuite" , alias = "testcase" , default ) ]
35+ test_results : Vec < TestResult > ,
3536}
3637
3738#[ derive( Debug , Deserialize , PartialEq ) ]
38- struct Testsuite {
39- filepath : PathBuf ,
39+ struct TestResult {
40+ #[ serde( alias = "filepath" , default ) ]
41+ file : Option < PathBuf > ,
4042 time : f64 ,
43+ #[ serde( rename = "testsuite" , alias = "testcase" , default ) ]
44+ test_results : Vec < TestResult > ,
45+ }
46+
47+ struct TestResultData {
48+ file : Option < PathBuf > ,
49+ time : f64 ,
50+ }
51+
52+ impl IntoIterator for TestResultXml {
53+ type IntoIter = IntoIter ;
54+ type Item = TestResultData ;
55+
56+ fn into_iter ( self ) -> Self :: IntoIter {
57+ IntoIter {
58+ remaining : self . test_results . into_iter ( ) . collect ( ) ,
59+ }
60+ }
61+ }
62+
63+ struct IntoIter {
64+ remaining : VecDeque < TestResult > ,
65+ }
66+
67+ impl Iterator for IntoIter {
68+ type Item = TestResultData ;
69+
70+ fn next ( & mut self ) -> Option < Self :: Item > {
71+ self . remaining . pop_front ( ) . and_then (
72+ |TestResult {
73+ file,
74+ time,
75+ test_results,
76+ } | {
77+ self . remaining . extend ( test_results) ;
78+
79+ Some ( TestResultData {
80+ file : file,
81+ time : time,
82+ } )
83+ } ,
84+ )
85+ }
4186}
4287
4388struct Node < ' a > {
@@ -80,14 +125,20 @@ fn get_test_file_results(
80125
81126 for xml_path in expand_globs ( & vec ! [ String :: from( xml_glob) ] ) ? {
82127 let reader = BufReader :: new ( File :: open ( xml_path) ?) ;
83- let testsuites: Testsuites = from_reader ( reader) ?;
84-
85- for suite in testsuites. testsuites {
86- let total_time = test_file_results. entry ( suite. filepath ) . or_insert ( 0.0 ) ;
87- * total_time += suite. time ;
128+ let test_result_xml: TestResultXml = from_reader ( reader) ?;
129+
130+ for TestResultData { file, time } in test_result_xml {
131+ file. map ( |f| {
132+ canonicalize ( f) . map ( |normalized_file| {
133+ let total_time = test_file_results. entry ( normalized_file) . or_insert ( 0.0 ) ;
134+ * total_time += time;
135+ } )
136+ } ) ;
88137 }
89138 }
90139
140+ debug ! ( "{:?}" , test_file_results) ;
141+
91142 Ok ( test_file_results)
92143}
93144
@@ -159,3 +210,10 @@ fn main() -> Result<()> {
159210
160211 Ok ( ( ) )
161212}
213+
214+ /*
215+ TODOS:
216+
217+ - Test <testsuites><testsuite file="/foo" time="0.1"></testsuite></testsuites>
218+ - Test <testsuite><testcase file="./foo" time="0.1"></testcase></testsuite>
219+ */
0 commit comments