@@ -72,14 +72,8 @@ impl Run for TestCommand {
72
72
self . log_action_context ( "output" , & testcase. output_file . display ( ) ) ;
73
73
testcase. build_lib ( manifest) ;
74
74
}
75
- TestType :: Runtime => {
76
- self . log_action_start ( "TEST Runtime" , & testcase. name ) ;
77
- self . log_action_context ( "source" , & testcase. source . display ( ) ) ;
78
- self . log_action_context ( "output" , & testcase. output_file . display ( ) ) ;
79
- testcase. build ( manifest) ;
80
- self . run_and_check_output ( & testcase) ;
81
- }
82
75
}
76
+ self . check_and_run_directives ( & testcase) ;
83
77
}
84
78
}
85
79
@@ -123,20 +117,6 @@ impl TestCommand {
123
117
cases. push ( testcase) ;
124
118
}
125
119
126
- // Runtime tests
127
- for case in glob ( "tests/runit/*.rs" ) . unwrap ( ) {
128
- let case = case. unwrap ( ) ;
129
- let filename = case. file_stem ( ) . unwrap ( ) ;
130
- // Skip the test runner
131
- if filename == "runner" {
132
- continue ;
133
- }
134
- let name = format ! ( "runit/{}" , filename. to_string_lossy( ) ) ;
135
- let output_file = manifest. out_dir . join ( "tests/runit" ) . join ( filename) ;
136
- let testcase = TestCase :: new ( name, case, output_file, TestType :: Runtime , verbose) ;
137
- cases. push ( testcase) ;
138
- }
139
-
140
120
// Collect and process auxiliary builds from directives
141
121
let mut auxiliaries = vec ! [ ] ;
142
122
for case in cases. iter ( ) {
@@ -197,11 +177,48 @@ impl TestCommand {
197
177
}
198
178
199
179
/// Run a runtime test and check its output against directives
200
- fn run_and_check_output ( & self , testcase : & TestCase ) {
180
+ fn check_and_run_directives ( & self , testcase : & TestCase ) {
201
181
// Parse directives from source
202
182
let directives = testcase. parse_directives ( ) ;
203
183
self . log_action_context ( "directives" , & format ! ( "found {} directives" , directives. len( ) ) ) ;
204
184
185
+ let mut runpass = false ;
186
+ let mut exitcode = None ;
187
+ let mut stdout = None ;
188
+ let mut stderr = None ;
189
+
190
+ // Check each directive
191
+ for directive in directives {
192
+ match directive {
193
+ TestDirective :: RunPass => runpass = true ,
194
+ TestDirective :: CheckStdout ( expected) => stdout = Some ( expected) ,
195
+ TestDirective :: CheckStderr ( expected) => stderr = Some ( expected) ,
196
+ TestDirective :: ExitCode ( expected) => exitcode = Some ( expected) ,
197
+ TestDirective :: AuxBuild ( _) => {
198
+ // AuxBuild directives are handled during test collection
199
+ // No need to check them during test execution
200
+ }
201
+ }
202
+ }
203
+
204
+ if !runpass && ( exitcode. is_some ( ) | stdout. is_some ( ) | stderr. is_some ( ) ) {
205
+ panic ! ( "Directives conflicts, lack of '//@ run-pass'" ) ;
206
+ }
207
+
208
+ if runpass {
209
+ self . run_and_check_output ( testcase, exitcode, stdout, stderr) ;
210
+ }
211
+
212
+ self . log_action_context ( "result" , "all checks passed" ) ;
213
+ }
214
+
215
+ fn run_and_check_output (
216
+ & self ,
217
+ testcase : & TestCase ,
218
+ expected_exit : Option < i32 > ,
219
+ expected_stdout : Option < String > ,
220
+ expected_stderr : Option < String > ,
221
+ ) {
205
222
// Run the test
206
223
self . log_action_context ( "running" , & testcase. output_file . display ( ) ) ;
207
224
let output = std:: process:: Command :: new ( & testcase. output_file )
@@ -215,63 +232,53 @@ impl TestCommand {
215
232
let actual_stdout = String :: from_utf8_lossy ( & output. stdout ) . into_owned ( ) ;
216
233
let actual_stderr = String :: from_utf8_lossy ( & output. stderr ) . into_owned ( ) ;
217
234
218
- // Check each directive
219
- for directive in directives {
220
- match directive {
221
- TestDirective :: CheckStdout ( expected) => {
222
- self . log_action_context ( "checking stdout" , & expected) ;
223
- let diff = TextDiff :: from_lines ( & expected, & actual_stdout) ;
224
- if diff. ratio ( ) < 1.0 {
225
- cprintln ! ( "<r,s>stdout does not match expected output</r,s>" ) ;
226
- for change in diff. iter_all_changes ( ) {
227
- let lineno =
228
- change. old_index ( ) . unwrap_or ( change. new_index ( ) . unwrap_or ( 0 ) ) ;
229
- match change. tag ( ) {
230
- ChangeTag :: Equal => print ! ( " {:4}| {}" , lineno, change) ,
231
- ChangeTag :: Insert => cprint ! ( "<g>+{:4}| {}</g>" , lineno, change) ,
232
- ChangeTag :: Delete => cprint ! ( "<r>-{:4}| {}</r>" , lineno, change) ,
233
- }
234
- }
235
- std:: process:: exit ( 1 ) ;
236
- }
237
- self . log_action_context ( "stdout" , "passed" ) ;
238
- }
239
- TestDirective :: CheckStderr ( expected) => {
240
- self . log_action_context ( "checking stderr" , & expected) ;
241
- let diff = TextDiff :: from_lines ( & expected, & actual_stderr) ;
242
- if diff. ratio ( ) < 1.0 {
243
- cprintln ! ( "<r,s>stderr does not match expected output</r,s>" ) ;
244
- for change in diff. iter_all_changes ( ) {
245
- let lineno =
246
- change. old_index ( ) . unwrap_or ( change. new_index ( ) . unwrap_or ( 0 ) ) ;
247
- match change. tag ( ) {
248
- ChangeTag :: Equal => print ! ( " {:4}| {}" , lineno, change) ,
249
- ChangeTag :: Insert => cprint ! ( "<g>+{:4}| {}</g>" , lineno, change) ,
250
- ChangeTag :: Delete => cprint ! ( "<r>-{:4}| {}</r>" , lineno, change) ,
251
- }
252
- }
253
- std:: process:: exit ( 1 ) ;
235
+ {
236
+ let expected_exit = expected_exit. unwrap_or ( 0 ) ;
237
+ self . log_action_context ( "checking exit code" , & expected_exit. to_string ( ) ) ;
238
+ if actual_return != expected_exit {
239
+ cprintln ! ( "<r,s>exit code does not match expected value</r,s>" ) ;
240
+ cprintln ! ( "expected: {}" , expected_exit) ;
241
+ cprintln ! ( "actual: {}" , actual_return) ;
242
+ std:: process:: exit ( 1 ) ;
243
+ }
244
+ self . log_action_context ( "exit code" , "passed" ) ;
245
+ }
246
+
247
+ if let Some ( expected_stdout) = expected_stdout {
248
+ self . log_action_context ( "checking stdout" , & expected_stdout) ;
249
+ let diff = TextDiff :: from_lines ( & expected_stdout, & actual_stdout) ;
250
+ if diff. ratio ( ) < 1.0 {
251
+ cprintln ! ( "<r,s>stdout does not match expected output</r,s>" ) ;
252
+ for change in diff. iter_all_changes ( ) {
253
+ let lineno = change. old_index ( ) . unwrap_or ( change. new_index ( ) . unwrap_or ( 0 ) ) ;
254
+ match change. tag ( ) {
255
+ ChangeTag :: Equal => print ! ( " {:4}| {}" , lineno, change) ,
256
+ ChangeTag :: Insert => cprint ! ( "<g>+{:4}| {}</g>" , lineno, change) ,
257
+ ChangeTag :: Delete => cprint ! ( "<r>-{:4}| {}</r>" , lineno, change) ,
254
258
}
255
- self . log_action_context ( "stderr" , "passed" ) ;
256
259
}
257
- TestDirective :: ExitCode ( expected) => {
258
- self . log_action_context ( "checking exit code" , & expected. to_string ( ) ) ;
259
- if actual_return != expected {
260
- cprintln ! ( "<r,s>exit code does not match expected value</r,s>" ) ;
261
- cprintln ! ( "expected: {}" , expected) ;
262
- cprintln ! ( "actual: {}" , actual_return) ;
263
- std:: process:: exit ( 1 ) ;
260
+ std:: process:: exit ( 1 ) ;
261
+ }
262
+ self . log_action_context ( "stdout" , "passed" ) ;
263
+ }
264
+
265
+ if let Some ( expected_stderr) = expected_stderr {
266
+ self . log_action_context ( "checking stderr" , & expected_stderr) ;
267
+ let diff = TextDiff :: from_lines ( & expected_stderr, & actual_stderr) ;
268
+ if diff. ratio ( ) < 1.0 {
269
+ cprintln ! ( "<r,s>stderr does not match expected output</r,s>" ) ;
270
+ for change in diff. iter_all_changes ( ) {
271
+ let lineno = change. old_index ( ) . unwrap_or ( change. new_index ( ) . unwrap_or ( 0 ) ) ;
272
+ match change. tag ( ) {
273
+ ChangeTag :: Equal => print ! ( " {:4}| {}" , lineno, change) ,
274
+ ChangeTag :: Insert => cprint ! ( "<g>+{:4}| {}</g>" , lineno, change) ,
275
+ ChangeTag :: Delete => cprint ! ( "<r>-{:4}| {}</r>" , lineno, change) ,
264
276
}
265
- self . log_action_context ( "exit code" , "passed" ) ;
266
- }
267
- TestDirective :: AuxBuild ( _) => {
268
- // AuxBuild directives are handled during test collection
269
- // No need to check them during test execution
270
277
}
278
+ std:: process:: exit ( 1 ) ;
271
279
}
280
+ self . log_action_context ( "stderr" , "passed" ) ;
272
281
}
273
-
274
- self . log_action_context ( "result" , "all checks passed" ) ;
275
282
}
276
283
}
277
284
@@ -285,8 +292,6 @@ pub enum TestType {
285
292
FileCheck ,
286
293
/// Bless test - the output should be the same as the last run
287
294
Bless ,
288
- /// Runtime test - compile, run and compare output
289
- Runtime ,
290
295
}
291
296
292
297
impl TestType {
@@ -296,7 +301,6 @@ impl TestType {
296
301
TestType :: CompileLib => "compile-lib" ,
297
302
TestType :: FileCheck => "filecheck" ,
298
303
TestType :: Bless => "bless" ,
299
- TestType :: Runtime => "runtime" ,
300
304
}
301
305
}
302
306
}
@@ -381,6 +385,7 @@ impl TestCase {
381
385
let mut directives = Vec :: new ( ) ;
382
386
383
387
// Regular expressions for matching directives
388
+ let run_pass = regex:: Regex :: new ( r"^//@\s*run-pass" ) . unwrap ( ) ;
384
389
let stdout_re = regex:: Regex :: new ( r"^//@\s*check-stdout:\s*(.*)" ) . unwrap ( ) ;
385
390
let stderr_re = regex:: Regex :: new ( r"^//@\s*check-stderr:\s*(.*)" ) . unwrap ( ) ;
386
391
let exit_re = regex:: Regex :: new ( r"^//@\s*exit-code:\s*(\d+)" ) . unwrap ( ) ;
@@ -389,7 +394,9 @@ impl TestCase {
389
394
let directive_re = regex:: Regex :: new ( r"^//@\s*([^:]+)" ) . unwrap ( ) ;
390
395
391
396
for ( line_num, line) in source. lines ( ) . enumerate ( ) {
392
- if let Some ( cap) = stdout_re. captures ( line) {
397
+ if let Some ( _cap) = run_pass. captures ( line) {
398
+ directives. push ( TestDirective :: RunPass ) ;
399
+ } else if let Some ( cap) = stdout_re. captures ( line) {
393
400
let content = cap[ 1 ] . trim ( ) . to_string ( ) ;
394
401
directives. push ( TestDirective :: CheckStdout ( content) ) ;
395
402
} else if let Some ( cap) = stderr_re. captures ( line) {
@@ -471,6 +478,9 @@ impl FileChecker {
471
478
/// Test directives that can appear in source files
472
479
#[ derive( Debug ) ]
473
480
enum TestDirective {
481
+ /// Compile and run a testcase,
482
+ /// expect a success (exit with 0)
483
+ RunPass ,
474
484
/// Expected stdout content
475
485
CheckStdout ( String ) ,
476
486
/// Expected stderr content
0 commit comments