@@ -31,7 +31,6 @@ use std::result;
31
31
use std:: task;
32
32
use std:: to_str:: ToStr ;
33
33
use std:: u64;
34
- use std:: uint;
35
34
36
35
37
36
// The name of a test. By convention this follows the rules for rust
@@ -191,6 +190,7 @@ pub enum TestResult { TrOk, TrFailed, TrIgnored, TrBench(BenchSamples) }
191
190
struct ConsoleTestState {
192
191
out : @io:: Writer ,
193
192
log_out : Option < @io:: Writer > ,
193
+ term : Option < term:: Terminal > ,
194
194
use_color : bool ,
195
195
total : uint ,
196
196
passed : uint ,
@@ -200,171 +200,180 @@ struct ConsoleTestState {
200
200
failures : ~[ TestDesc ]
201
201
}
202
202
203
- // A simple console test runner
204
- pub fn run_tests_console( opts : & TestOpts ,
205
- tests : ~[ TestDescAndFn ] ) -> bool {
206
- fn callback ( event : & TestEvent , st : & mut ConsoleTestState ) {
207
- debug ! ( "callback(event=%?)" , event) ;
208
- match copy * event {
209
- TeFiltered ( ref filtered_tests) => {
210
- st. total = filtered_tests. len ( ) ;
211
- let noun = if st. total != 1 { ~"tests" } else { ~"test" } ;
212
- st. out . write_line ( fmt ! ( "\n running %u %s" , st. total, noun) ) ;
213
- }
214
- TeWait ( ref test) => st. out . write_str (
215
- fmt ! ( "test %s ... " , test. name. to_str( ) ) ) ,
216
- TeResult ( test, result) => {
217
- match st. log_out {
218
- Some ( f) => write_log ( f, copy result, & test) ,
219
- None => ( )
220
- }
221
- match result {
222
- TrOk => {
223
- st. passed += 1 ;
224
- write_ok ( st. out , st. use_color ) ;
225
- st. out . write_line ( "" ) ;
226
- }
227
- TrFailed => {
228
- st. failed += 1 ;
229
- write_failed ( st. out , st. use_color ) ;
230
- st. out . write_line ( "" ) ;
231
- st. failures . push ( test) ;
232
- }
233
- TrIgnored => {
234
- st. ignored += 1 ;
235
- write_ignored ( st. out , st. use_color ) ;
236
- st. out . write_line ( "" ) ;
237
- }
238
- TrBench ( bs) => {
239
- st. benchmarked += 1 u;
240
- write_bench ( st. out , st. use_color ) ;
241
- st. out . write_line ( fmt ! ( ": %s" ,
242
- fmt_bench_samples( & bs) ) ) ;
243
- }
244
- }
245
- }
203
+ impl ConsoleTestState {
204
+ pub fn new ( opts : & TestOpts ) -> ConsoleTestState {
205
+ let log_out = match opts. logfile {
206
+ Some ( ref path) => match io:: file_writer ( path,
207
+ [ io:: Create ,
208
+ io:: Truncate ] ) {
209
+ result:: Ok ( w) => Some ( w) ,
210
+ result:: Err ( ref s) => {
211
+ fail ! ( "can't open output file: %s" , * s)
212
+ }
213
+ } ,
214
+ None => None
215
+ } ;
216
+ let out = io:: stdout ( ) ;
217
+ let term = match term:: Terminal :: new ( out) {
218
+ Err ( _) => None ,
219
+ Ok ( t) => Some ( t)
220
+ } ;
221
+ ConsoleTestState {
222
+ out : out,
223
+ log_out : log_out,
224
+ use_color : use_color ( ) ,
225
+ term : term,
226
+ total : 0 u,
227
+ passed : 0 u,
228
+ failed : 0 u,
229
+ ignored : 0 u,
230
+ benchmarked : 0 u,
231
+ failures : ~[ ]
246
232
}
247
233
}
248
234
249
- let log_out = match opts. logfile {
250
- Some ( ref path) => match io:: file_writer ( path,
251
- [ io:: Create ,
252
- io:: Truncate ] ) {
253
- result:: Ok ( w) => Some ( w) ,
254
- result:: Err ( ref s) => {
255
- fail ! ( "can't open output file: %s" , * s)
256
- }
257
- } ,
258
- None => None
259
- } ;
260
-
261
- let st = @mut ConsoleTestState {
262
- out : io:: stdout ( ) ,
263
- log_out : log_out,
264
- use_color : use_color ( ) ,
265
- total : 0 u,
266
- passed : 0 u,
267
- failed : 0 u,
268
- ignored : 0 u,
269
- benchmarked : 0 u,
270
- failures : ~[ ]
271
- } ;
272
-
273
- run_tests ( opts, tests, |x| callback ( & x, st) ) ;
274
-
275
- assert ! ( st. passed + st. failed +
276
- st. ignored + st. benchmarked == st. total) ;
277
- let success = st. failed == 0 u;
235
+ pub fn write_ok ( & self ) {
236
+ self . write_pretty ( "ok" , term:: color:: GREEN ) ;
237
+ }
278
238
279
- if !success {
280
- print_failures ( st ) ;
239
+ pub fn write_failed ( & self ) {
240
+ self . write_pretty ( "FAILED" , term :: color :: RED ) ;
281
241
}
282
242
283
- {
284
- let st: & mut ConsoleTestState = st;
285
- st. out . write_str ( fmt ! ( "\n result: " ) ) ;
286
- if success {
287
- // There's no parallelism at this point so it's safe to use color
288
- write_ok ( st. out , true ) ;
289
- } else {
290
- write_failed ( st. out , true ) ;
291
- }
292
- st. out . write_str ( fmt ! ( ". %u passed; %u failed; %u ignored\n \n " ,
293
- st. passed, st. failed, st. ignored) ) ;
243
+ pub fn write_ignored ( & self ) {
244
+ self . write_pretty ( "ignored" , term:: color:: YELLOW ) ;
294
245
}
295
246
296
- return success;
247
+ pub fn write_bench ( & self ) {
248
+ self . write_pretty ( "bench" , term:: color:: CYAN ) ;
249
+ }
297
250
298
- fn fmt_bench_samples ( bs : & BenchSamples ) -> ~str {
299
- if bs. mb_s != 0 {
300
- fmt ! ( "%u ns/iter (+/- %u) = %u MB/s" ,
301
- bs. ns_iter_summ. median as uint,
302
- ( bs. ns_iter_summ. max - bs. ns_iter_summ. min) as uint,
303
- bs. mb_s)
304
- } else {
305
- fmt ! ( "%u ns/iter (+/- %u)" ,
306
- bs. ns_iter_summ. median as uint,
307
- ( bs. ns_iter_summ. max - bs. ns_iter_summ. min) as uint)
251
+ pub fn write_pretty ( & self ,
252
+ word : & str ,
253
+ color : term:: color:: Color ) {
254
+ match self . term {
255
+ None => self . out . write_str ( word) ,
256
+ Some ( ref t) => {
257
+ if self . use_color {
258
+ t. fg ( color) ;
259
+ }
260
+ self . out . write_str ( word) ;
261
+ if self . use_color {
262
+ t. reset ( ) ;
263
+ }
264
+ }
308
265
}
309
266
}
310
267
311
- fn write_log( out : @io:: Writer , result : TestResult , test : & TestDesc ) {
312
- out. write_line ( fmt!( "%s %s" ,
313
- match result {
314
- TrOk => ~"ok",
315
- TrFailed => ~" failed",
316
- TrIgnored => ~" ignored",
317
- TrBench(ref bs) => fmt_bench_samples(bs)
318
- }, test.name.to_str()));
268
+ pub fn write_run_start ( & mut self , len : uint ) {
269
+ self . total = len;
270
+ let noun = if len != 1 { & "tests" } else { & "test" } ;
271
+ self . out . write_line ( fmt ! ( "\n running %u %s" , len, noun) ) ;
319
272
}
320
273
321
- fn write_ok(out: @io::Writer, use_color: bool ) {
322
- write_pretty( out, " ok ", term::color::GREEN, use_color );
274
+ pub fn write_test_start ( & self , test : & TestDesc ) {
275
+ self . out . write_str ( fmt ! ( "test %s ... " , test . name . to_str ( ) ) ) ;
323
276
}
324
277
325
- fn write_failed(out: @io::Writer, use_color: bool) {
326
- write_pretty(out, " FAILED ", term::color::RED, use_color);
278
+ pub fn write_result ( & self , result : & TestResult ) {
279
+ match * result {
280
+ TrOk => self . write_ok ( ) ,
281
+ TrFailed => self . write_failed ( ) ,
282
+ TrIgnored => self . write_ignored ( ) ,
283
+ TrBench ( ref bs) => {
284
+ self . write_bench ( ) ;
285
+ self . out . write_str ( ": " + fmt_bench_samples ( bs) )
286
+ }
287
+ }
288
+ self . out . write_str ( & "\n " ) ;
289
+ }
290
+
291
+ pub fn write_log( & self , test : & TestDesc , result : & TestResult ) {
292
+ match self . log_out {
293
+ None => ( ) ,
294
+ Some ( out) => {
295
+ out. write_line ( fmt ! ( "%s %s" ,
296
+ match * result {
297
+ TrOk => ~"ok",
298
+ TrFailed => ~" failed",
299
+ TrIgnored => ~" ignored",
300
+ TrBench(ref bs) => fmt_bench_samples(bs)
301
+ }, test.name.to_str()));
302
+ }
303
+ }
327
304
}
328
305
329
- fn write_ignored(out: @io::Writer, use_color: bool) {
330
- write_pretty(out, " ignored", term::color::YELLOW, use_color);
306
+ pub fn write_failures(&self) {
307
+ self.out.write_line(" \n failures: ");
308
+ let mut failures = ~[];
309
+ for self.failures.iter().advance() |f| {
310
+ failures.push(f.name.to_str());
311
+ }
312
+ sort::tim_sort(failures);
313
+ for failures.iter().advance |name| {
314
+ self.out.write_line(fmt!(" %s", name.to_str()));
315
+ }
331
316
}
332
317
333
- fn write_bench(out: @io::Writer, use_color: bool) {
334
- write_pretty(out, " bench", term::color::CYAN, use_color);
335
- }
318
+ pub fn write_run_finish(&self) -> bool {
319
+ assert!(self.passed + self.failed + self.ignored + self.benchmarked == self.total);
320
+ let success = self.failed == 0u;
321
+ if !success {
322
+ self.write_failures();
323
+ }
336
324
337
- fn write_pretty(out: @io::Writer,
338
- word: &str,
339
- color: term::color::Color,
340
- use_color: bool) {
341
- let t = term::Terminal::new(out);
342
- match t {
343
- Ok(term) => {
344
- if use_color {
345
- term.fg(color);
346
- }
347
- out.write_str(word);
348
- if use_color {
349
- term.reset();
350
- }
351
- },
352
- Err(_) => out.write_str(word)
325
+ self.out.write_str(" \n result: ");
326
+ if success {
327
+ // There's no parallelism at this point so it's safe to use color
328
+ self.write_ok();
329
+ } else {
330
+ self.write_failed();
353
331
}
332
+ self.out.write_str(fmt!(" . %u passed; %u failed; %u ignored, %u benchmarked\n \n ",
333
+ self . passed, self . failed, self . ignored, self . benchmarked) ) ;
334
+ return success;
354
335
}
355
336
}
356
337
357
- fn print_failures(st: &ConsoleTestState) {
358
- st.out.write_line(" \n failures: ");
359
- let mut failures = ~[];
360
- for uint::range(0, st.failures.len()) |i| {
361
- let name = copy st.failures[i].name;
362
- failures.push(name.to_str());
338
+ pub fn fmt_bench_samples ( bs : & BenchSamples ) -> ~str {
339
+ if bs. mb_s != 0 {
340
+ fmt ! ( "%u ns/iter (+/- %u) = %u MB/s" ,
341
+ bs. ns_iter_summ. median as uint,
342
+ ( bs. ns_iter_summ. max - bs. ns_iter_summ. min) as uint,
343
+ bs. mb_s)
344
+ } else {
345
+ fmt ! ( "%u ns/iter (+/- %u)" ,
346
+ bs. ns_iter_summ. median as uint,
347
+ ( bs. ns_iter_summ. max - bs. ns_iter_summ. min) as uint)
363
348
}
364
- sort::tim_sort(failures);
365
- for failures.iter().advance |name| {
366
- st.out.write_line(fmt!(" %s", name.to_str()));
349
+ }
350
+
351
+ // A simple console test runner
352
+ pub fn run_tests_console ( opts : & TestOpts ,
353
+ tests : ~[ TestDescAndFn ] ) -> bool {
354
+ fn callback ( event : & TestEvent , st : & mut ConsoleTestState ) {
355
+ debug ! ( "callback(event=%?)" , event) ;
356
+ match copy * event {
357
+ TeFiltered ( ref filtered_tests) => st. write_run_start ( filtered_tests. len ( ) ) ,
358
+ TeWait ( ref test) => st. write_test_start ( test) ,
359
+ TeResult ( test, result) => {
360
+ st. write_log ( & test, & result) ;
361
+ st. write_result ( & result) ;
362
+ match result {
363
+ TrOk => st. passed += 1 ,
364
+ TrIgnored => st. ignored += 1 ,
365
+ TrBench ( _) => st. benchmarked += 1 ,
366
+ TrFailed => {
367
+ st. failed += 1 ;
368
+ st. failures . push ( test) ;
369
+ }
370
+ }
371
+ }
372
+ }
367
373
}
374
+ let st = @mut ConsoleTestState :: new ( opts) ;
375
+ run_tests ( opts, tests, |x| callback ( & x, st) ) ;
376
+ return st. write_run_finish ( ) ;
368
377
}
369
378
370
379
#[ test]
0 commit comments