2121
2222use i_slint_compiler:: diagnostics:: { BuildDiagnostics , Diagnostic , DiagnosticLevel } ;
2323use i_slint_compiler:: ComponentSelection ;
24+ use std:: ops:: Range ;
2425use std:: path:: { Path , PathBuf } ;
2526
2627#[ test]
@@ -96,36 +97,16 @@ fn process_file(path: &std::path::Path, update: bool) -> std::io::Result<bool> {
9697 )
9798}
9899
99- fn process_diagnostics (
100- compile_diagnostics : & BuildDiagnostics ,
101- path : & Path ,
102- source : & str ,
103- _silent : bool ,
104- update : bool ,
105- ) -> std:: io:: Result < bool > {
106- let mut success = true ;
107-
108- let path = canonical ( path) ;
109-
110- let mut diags = compile_diagnostics
111- . iter ( )
112- . filter ( |d| {
113- canonical (
114- d. source_file ( )
115- . unwrap_or_else ( || panic ! ( "{path:?}: Error without a source file {d:?}" , ) ) ,
116- ) == path
117- } )
118- . collect :: < Vec < _ > > ( ) ;
119-
120- let lines = source
121- . bytes ( )
122- . enumerate ( )
123- . filter_map ( |( i, c) | if c == b'\n' { Some ( i) } else { None } )
124- . collect :: < Vec < usize > > ( ) ;
125-
126- let diag_copy = diags. clone ( ) ;
127- let mut captures = Vec :: new ( ) ;
100+ struct ExpectedDiagnostic {
101+ start : usize ,
102+ end : Option < usize > ,
103+ level : DiagnosticLevel ,
104+ message : String ,
105+ comment_range : Range < usize > ,
106+ }
128107
108+ fn extract_expected_diags ( source : & str ) -> Vec < ExpectedDiagnostic > {
109+ let mut expected = Vec :: new ( ) ;
129110 // Find expected errors in the file. The first caret (^) points to the expected column. The number of
130111 // carets refers to the number of lines to go back. This is useful when one line of code produces multiple
131112 // errors or warnings.
@@ -137,9 +118,7 @@ fn process_diagnostics(
137118 let warning_or_error = m. get ( 2 ) . unwrap ( ) . as_str ( ) ;
138119 let expected_message =
139120 m. get ( 3 ) . unwrap ( ) . as_str ( ) . replace ( '↵' , "\n " ) . replace ( '📂' , env ! ( "CARGO_MANIFEST_DIR" ) ) ;
140- if update {
141- captures. push ( m. get ( 0 ) . unwrap ( ) . range ( ) ) ;
142- }
121+ let comment_range = m. get ( 0 ) . unwrap ( ) . range ( ) ;
143122
144123 let mut line_counter = 0 ;
145124 let mut line_offset = source[ ..line_begin_offset] . rfind ( '\n' ) . unwrap_or ( 0 ) ;
@@ -161,6 +140,54 @@ fn process_diagnostics(
161140 _ => panic ! ( "Unsupported diagnostic level {warning_or_error}" ) ,
162141 } ;
163142
143+ expected. push ( ExpectedDiagnostic {
144+ start : offset,
145+ end : None ,
146+ level : expected_diag_level,
147+ message : expected_message,
148+ comment_range,
149+ } ) ;
150+ }
151+ expected
152+ }
153+
154+ fn process_diagnostics (
155+ compile_diagnostics : & BuildDiagnostics ,
156+ path : & Path ,
157+ source : & str ,
158+ _silent : bool ,
159+ update : bool ,
160+ ) -> std:: io:: Result < bool > {
161+ let mut success = true ;
162+
163+ let path = canonical ( path) ;
164+
165+ let mut diags = compile_diagnostics
166+ . iter ( )
167+ . filter ( |d| {
168+ canonical (
169+ d. source_file ( )
170+ . unwrap_or_else ( || panic ! ( "{path:?}: Error without a source file {d:?}" , ) ) ,
171+ ) == path
172+ } )
173+ . collect :: < Vec < _ > > ( ) ;
174+
175+ let lines = source
176+ . bytes ( )
177+ . enumerate ( )
178+ . filter_map ( |( i, c) | if c == b'\n' { Some ( i) } else { None } )
179+ . collect :: < Vec < usize > > ( ) ;
180+
181+ let diag_copy = diags. clone ( ) ;
182+
183+ let expected = extract_expected_diags ( source) ;
184+ let captures: Vec < _ > =
185+ expected. iter ( ) . map ( |expected| & expected. comment_range ) . cloned ( ) . collect ( ) ;
186+
187+ // Find expected errors in the file. The first caret (^) points to the expected column. The number of
188+ // carets refers to the number of lines to go back. This is useful when one line of code produces multiple
189+ // errors or warnings.
190+ for expected in expected {
164191 fn compare_message ( message : & str , expected_message : & str ) -> bool {
165192 if message == expected_message {
166193 return true ;
@@ -175,17 +202,22 @@ fn process_diagnostics(
175202
176203 match diags. iter ( ) . position ( |e| {
177204 let ( l, c) = e. line_column ( ) ;
178- let o = lines. get ( l. wrapping_sub ( 2 ) ) . unwrap_or ( & 0 ) + c;
179- o == offset
180- && compare_message ( e. message ( ) , & expected_message )
181- && e. level ( ) == expected_diag_level
205+ let diag_start = lines. get ( l. wrapping_sub ( 2 ) ) . unwrap_or ( & 0 ) + c;
206+ diag_start == expected . start
207+ && compare_message ( e. message ( ) , & expected . message )
208+ && e. level ( ) == expected . level
182209 } ) {
183210 Some ( idx) => {
184211 diags. remove ( idx) ;
185212 }
186213 None => {
187214 success = false ;
188- println ! ( "{path:?}: {warning_or_error} not found at offset {offset}: {expected_message:?}" ) ;
215+ println ! (
216+ "{path:?}: {level:?} not found at offset {offset}: {message:?}" ,
217+ level = expected. level,
218+ offset = expected. start,
219+ message = expected. message
220+ ) ;
189221 }
190222 }
191223 }
0 commit comments