7
7
//! to reimplement all the rendering logic in this module because of that.
8
8
9
9
use crate :: builder:: Builder ;
10
- use std:: io:: { BufRead , BufReader } ;
10
+ use std:: io:: { BufRead , BufReader , Write } ;
11
11
use std:: process:: { ChildStdout , Command , Stdio } ;
12
12
use std:: time:: Duration ;
13
13
14
+ const TERSE_TESTS_PER_LINE : usize = 88 ;
15
+
14
16
pub ( crate ) fn try_run_tests ( builder : & Builder < ' _ > , cmd : & mut Command ) -> bool {
15
17
if builder. config . dry_run ( ) {
16
18
return true ;
@@ -36,7 +38,8 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut Command) -> bool {
36
38
37
39
let mut process = cmd. spawn ( ) . unwrap ( ) ;
38
40
let stdout = process. stdout . take ( ) . unwrap ( ) ;
39
- let handle = std:: thread:: spawn ( move || Renderer :: new ( stdout) . render_all ( ) ) ;
41
+ let verbose = builder. config . verbose_tests ;
42
+ let handle = std:: thread:: spawn ( move || Renderer :: new ( stdout, verbose) . render_all ( ) ) ;
40
43
41
44
let result = process. wait ( ) . unwrap ( ) ;
42
45
handle. join ( ) . expect ( "test formatter thread failed" ) ;
@@ -54,11 +57,22 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut Command) -> bool {
54
57
struct Renderer {
55
58
stdout : BufReader < ChildStdout > ,
56
59
failures : Vec < TestOutcome > ,
60
+ verbose : bool ,
61
+ tests_count : Option < usize > ,
62
+ executed_tests : usize ,
63
+ terse_tests_in_line : usize ,
57
64
}
58
65
59
66
impl Renderer {
60
- fn new ( stdout : ChildStdout ) -> Self {
61
- Self { stdout : BufReader :: new ( stdout) , failures : Vec :: new ( ) }
67
+ fn new ( stdout : ChildStdout , verbose : bool ) -> Self {
68
+ Self {
69
+ stdout : BufReader :: new ( stdout) ,
70
+ failures : Vec :: new ( ) ,
71
+ verbose,
72
+ tests_count : None ,
73
+ executed_tests : 0 ,
74
+ terse_tests_in_line : 0 ,
75
+ }
62
76
}
63
77
64
78
fn render_all ( mut self ) {
@@ -83,9 +97,13 @@ impl Renderer {
83
97
}
84
98
}
85
99
86
- fn render_test_outcome ( & self , outcome : Outcome < ' _ > , test : & TestOutcome ) {
87
- // TODO: add support for terse output
88
- self . render_test_outcome_verbose ( outcome, test) ;
100
+ fn render_test_outcome ( & mut self , outcome : Outcome < ' _ > , test : & TestOutcome ) {
101
+ self . executed_tests += 1 ;
102
+ if self . verbose {
103
+ self . render_test_outcome_verbose ( outcome, test) ;
104
+ } else {
105
+ self . render_test_outcome_terse ( outcome, test) ;
106
+ }
89
107
}
90
108
91
109
fn render_test_outcome_verbose ( & self , outcome : Outcome < ' _ > , test : & TestOutcome ) {
@@ -100,7 +118,35 @@ impl Renderer {
100
118
}
101
119
}
102
120
121
+ fn render_test_outcome_terse ( & mut self , outcome : Outcome < ' _ > , _: & TestOutcome ) {
122
+ if self . terse_tests_in_line != 0 && self . terse_tests_in_line % TERSE_TESTS_PER_LINE == 0 {
123
+ if let Some ( total) = self . tests_count {
124
+ let total = total. to_string ( ) ;
125
+ let executed = format ! ( "{:>width$}" , self . executed_tests - 1 , width = total. len( ) ) ;
126
+ print ! ( " {executed}/{total}" ) ;
127
+ }
128
+ println ! ( ) ;
129
+ self . terse_tests_in_line = 0 ;
130
+ }
131
+
132
+ self . terse_tests_in_line += 1 ;
133
+ print ! (
134
+ "{}" ,
135
+ match outcome {
136
+ Outcome :: Ok => "." ,
137
+ Outcome :: Failed => "F" ,
138
+ Outcome :: Ignored { .. } => "i" ,
139
+ }
140
+ ) ;
141
+ let _ = std:: io:: stdout ( ) . flush ( ) ;
142
+ }
143
+
103
144
fn render_suite_outcome ( & self , outcome : Outcome < ' _ > , suite : & SuiteOutcome ) {
145
+ // The terse output doesn't end with a newline, so we need to add it ourselves.
146
+ if !self . verbose {
147
+ println ! ( ) ;
148
+ }
149
+
104
150
if !self . failures . is_empty ( ) {
105
151
println ! ( "\n failures:\n " ) ;
106
152
for failure in & self . failures {
@@ -132,6 +178,9 @@ impl Renderer {
132
178
match message {
133
179
Message :: Suite ( SuiteMessage :: Started { test_count } ) => {
134
180
println ! ( "\n running {test_count} tests" ) ;
181
+ self . executed_tests = 0 ;
182
+ self . terse_tests_in_line = 0 ;
183
+ self . tests_count = Some ( test_count) ;
135
184
}
136
185
Message :: Suite ( SuiteMessage :: Ok ( outcome) ) => {
137
186
self . render_suite_outcome ( Outcome :: Ok , & outcome) ;
0 commit comments