@@ -46,6 +46,8 @@ pub struct Config {
46
46
/// Can be used to override what command to run instead of `cargo` to build the
47
47
/// dependencies in `manifest_path`
48
48
pub dependency_builder : Option < DependencyBuilder > ,
49
+ /// Print one character per test instead of one line
50
+ pub quiet : bool ,
49
51
}
50
52
51
53
#[ derive( Debug ) ]
@@ -123,11 +125,50 @@ pub fn run_tests(mut config: Config) -> Result<()> {
123
125
drop ( submit) ;
124
126
} ) ;
125
127
128
+ // A channel for the messages emitted by the individual test threads.
129
+ let ( finished_files_sender, finished_files_recv) = crossbeam:: channel:: unbounded ( ) ;
130
+ enum TestResult {
131
+ Ok ,
132
+ Failed ,
133
+ Ignored ,
134
+ }
135
+
136
+ s. spawn ( |_| {
137
+ if config. quiet {
138
+ for ( i, ( _, result) ) in finished_files_recv. into_iter ( ) . enumerate ( ) {
139
+ // Humans start counting at 1
140
+ let i = i + 1 ;
141
+ match result {
142
+ TestResult :: Ok => eprint ! ( "{}" , "." . green( ) ) ,
143
+ TestResult :: Failed => eprint ! ( "{}" , "F" . red( ) . bold( ) ) ,
144
+ TestResult :: Ignored => eprint ! ( "{}" , "i" . yellow( ) ) ,
145
+ }
146
+ if i % 100 == 0 {
147
+ eprintln ! ( " {i}" ) ;
148
+ }
149
+ }
150
+ } else {
151
+ for ( msg, result) in finished_files_recv {
152
+ eprint ! ( "{msg} ... " ) ;
153
+ eprintln ! (
154
+ "{}" ,
155
+ match result {
156
+ TestResult :: Ok => "ok" . green( ) ,
157
+ TestResult :: Failed => "FAILED" . red( ) . bold( ) ,
158
+ TestResult :: Ignored => "ignored (in-test comment)" . yellow( ) ,
159
+ }
160
+ ) ;
161
+ }
162
+ }
163
+ } ) ;
164
+
126
165
let mut threads = vec ! [ ] ;
127
166
128
167
// Create N worker threads that receive files to test.
129
168
for _ in 0 ..std:: thread:: available_parallelism ( ) . unwrap ( ) . get ( ) {
169
+ let finished_files_sender = finished_files_sender. clone ( ) ;
130
170
threads. push ( s. spawn ( |_| -> Result < ( ) > {
171
+ let finished_files_sender = finished_files_sender;
131
172
for path in & receive {
132
173
if !config. path_filter . is_empty ( ) {
133
174
let path_display = path. display ( ) . to_string ( ) ;
@@ -140,11 +181,8 @@ pub fn run_tests(mut config: Config) -> Result<()> {
140
181
// Ignore file if only/ignore rules do (not) apply
141
182
if !test_file_conditions ( & comments, & target, & config) {
142
183
ignored. fetch_add ( 1 , Ordering :: Relaxed ) ;
143
- eprintln ! (
144
- "{} ... {}" ,
145
- path. display( ) ,
146
- "ignored (in-test comment)" . yellow( )
147
- ) ;
184
+ finished_files_sender
185
+ . send ( ( path. display ( ) . to_string ( ) , TestResult :: Ignored ) ) ?;
148
186
continue ;
149
187
}
150
188
// Run the test for all revisions
@@ -159,12 +197,11 @@ pub fn run_tests(mut config: Config) -> Result<()> {
159
197
if !revision. is_empty ( ) {
160
198
write ! ( msg, "(revision `{revision}`) " ) . unwrap ( ) ;
161
199
}
162
- write ! ( msg, "... " ) . unwrap ( ) ;
163
200
if errors. is_empty ( ) {
164
- eprintln ! ( "{ msg}{}" , "ok" . green ( ) ) ;
201
+ finished_files_sender . send ( ( msg, TestResult :: Ok ) ) ? ;
165
202
succeeded. fetch_add ( 1 , Ordering :: Relaxed ) ;
166
203
} else {
167
- eprintln ! ( "{ msg}{}" , "FAILED" . red ( ) . bold ( ) ) ;
204
+ finished_files_sender . send ( ( msg, TestResult :: Failed ) ) ? ;
168
205
failures. lock ( ) . unwrap ( ) . push ( (
169
206
path. clone ( ) ,
170
207
m,
@@ -178,6 +215,7 @@ pub fn run_tests(mut config: Config) -> Result<()> {
178
215
Ok ( ( ) )
179
216
} ) ) ;
180
217
}
218
+
181
219
for thread in threads {
182
220
thread. join ( ) . unwrap ( ) ?;
183
221
}
0 commit comments