@@ -99,105 +99,143 @@ fn run_tests_console(opts: &test_opts, tests: &test_desc[]) -> bool {
99
99
fn run_tests_console_( opts: & test_opts, tests: & test_desc[ ] ,
100
100
to_task: & test_to_task) -> bool {
101
101
102
- let filtered_tests = filter_tests( opts, tests) ;
103
-
104
- let out = io:: stdout( ) ;
105
-
106
- let total = ivec:: len( filtered_tests) ;
107
- out. write_line( #fmt( "\n running %u tests" , total) ) ;
108
-
109
- let futures = ~[ ] ;
110
-
111
- let passed = 0 u;
112
- let failed = 0 u;
113
- let ignored = 0 u;
114
-
115
- let failures = ~[ ] ;
116
-
117
- // It's tempting to just spawn all the tests at once but that doesn't
118
- // provide a great user experience because you might sit waiting for the
119
- // result of a particular test for an unusually long amount of time.
120
- let concurrency = get_concurrency( ) ;
121
- log #fmt( "using %u test tasks" , concurrency) ;
122
- let run_idx = 0 u;
123
- let wait_idx = 0 u;
124
-
125
- while wait_idx < total {
126
- while ivec:: len ( futures) < concurrency && run_idx < total {
127
- futures += ~[ run_test ( filtered_tests. ( run_idx) , to_task) ] ;
128
- run_idx += 1 u;
129
- }
130
-
131
- let future = futures. ( 0 ) ;
132
- out. write_str ( #fmt ( "running %s ... " , future. test . name ) ) ;
133
- let result = future. wait ( ) ;
134
- alt result {
135
- tr_ok. {
136
- passed += 1 u;
137
- write_ok ( out, concurrency) ;
138
- out. write_line ( "" ) ;
139
- }
140
- tr_failed. {
141
- failed += 1 u;
142
- write_failed ( out, concurrency) ;
143
- out. write_line ( "" ) ;
144
- failures += ~[ future. test ] ;
102
+ type test_state = @{
103
+ out : io:: writer,
104
+ use_color : bool,
105
+ mutable total: uint,
106
+ mutable passed: uint,
107
+ mutable failed: uint,
108
+ mutable ignored : uint,
109
+ mutable failures : test_desc[ ]
110
+ } ;
111
+
112
+ fn callback( event: testevent, st: test_state) {
113
+ alt event {
114
+ te_filtered( filtered_tests) {
115
+ st. total = ivec:: len( filtered_tests) ;
116
+ st. out. write_line( #fmt( "\n running %u tests" , st. total) ) ;
145
117
}
146
- tr_ignored. {
147
- ignored += 1 u;
148
- write_ignored ( out, concurrency) ;
149
- out. write_line ( "" ) ;
118
+ te_result( test, result) {
119
+ st. out. write_str( #fmt( "test %s ... " , test. name) ) ;
120
+ alt result {
121
+ tr_ok. {
122
+ st. passed += 1 u;
123
+ write_ok( st. out, st. use_color) ;
124
+ st. out. write_line( "" ) ;
125
+ }
126
+ tr_failed. {
127
+ st . failed += 1 u;
128
+ write_failed ( st. out , st. use_color ) ;
129
+ st. out . write_line ( "" ) ;
130
+ st. failures += ~[ test] ;
131
+ }
132
+ tr_ignored. {
133
+ st . ignored += 1 u;
134
+ write_ignored ( st. out , st. use_color ) ;
135
+ st. out . write_line ( "" ) ;
136
+ }
137
+ }
150
138
}
151
139
}
152
- futures = ivec:: slice( futures, 1 u, ivec:: len ( futures ) ) ;
153
- wait_idx += 1 u;
154
140
}
155
141
156
- assert ( passed + failed + ignored == total) ;
157
- let success = failed == 0 u;
142
+ let st = @{
143
+ out: io:: stdout ( ) ,
144
+ use_color: use_color ( ) ,
145
+ mutable total: 0 u,
146
+ mutable passed: 0 u,
147
+ mutable failed: 0 u,
148
+ mutable ignored: 0 u,
149
+ mutable failures: ~[ ]
150
+ } ;
151
+
152
+ run_tests( opts, tests, to_task,
153
+ bind callback ( _, st) ) ;
154
+
155
+ assert st. passed + st. failed + st. ignored == st. total ;
156
+ let success = st. failed == 0 u;
158
157
159
158
if !success {
160
- out. write_line ( "\n failures:" ) ;
161
- for test: test_desc in failures {
162
- out. write_line ( #fmt ( " %s" , test. name ) ) ;
159
+ st. out . write_line ( "\n failures:" ) ;
160
+ for test: test_desc in st. failures {
161
+ let testname = test. name ; // Satisfy alias analysis
162
+ st. out . write_line ( #fmt ( " %s" , testname) ) ;
163
163
}
164
164
}
165
165
166
- out. write_str ( #fmt ( "\n result: " ) ) ;
166
+ st . out . write_str ( #fmt ( "\n result: " ) ) ;
167
167
if success {
168
- write_ok ( out, concurrency ) ;
169
- } else { write_failed ( out, concurrency ) ; }
170
- out. write_str ( #fmt ( ". %u passed; %u failed; %u ignored\n \n " , passed ,
171
- failed, ignored) ) ;
168
+ write_ok ( st . out , st . use_color ) ;
169
+ } else { write_failed ( st . out , st . use_color ) ; }
170
+ st . out . write_str ( #fmt ( ". %u passed; %u failed; %u ignored\n \n " ,
171
+ st . passed , st . failed , st . ignored ) ) ;
172
172
173
173
ret success;
174
174
175
- fn write_ok ( out : & io:: writer , concurrency : uint ) {
176
- write_pretty ( out, "ok" , term:: color_green, concurrency ) ;
175
+ fn write_ok ( out : & io:: writer , use_color : bool ) {
176
+ write_pretty ( out, "ok" , term:: color_green, use_color ) ;
177
177
}
178
178
179
- fn write_failed ( out : & io:: writer , concurrency : uint ) {
180
- write_pretty ( out, "FAILED" , term:: color_red, concurrency ) ;
179
+ fn write_failed ( out : & io:: writer , use_color : bool ) {
180
+ write_pretty ( out, "FAILED" , term:: color_red, use_color ) ;
181
181
}
182
182
183
- fn write_ignored ( out : & io:: writer , concurrency : uint ) {
184
- write_pretty ( out, "ignored" , term:: color_yellow, concurrency ) ;
183
+ fn write_ignored ( out : & io:: writer , use_color : bool ) {
184
+ write_pretty ( out, "ignored" , term:: color_yellow, use_color ) ;
185
185
}
186
186
187
187
fn write_pretty ( out : & io:: writer , word : & str , color : u8 ,
188
- concurrency : uint ) {
189
- // In the presence of concurrency, outputing control characters
190
- // can cause some crazy artifacting
191
- if concurrency == 1 u && term:: color_supported ( ) {
188
+ use_color : bool ) {
189
+ if use_color && term:: color_supported ( ) {
192
190
term:: fg ( out. get_buf_writer ( ) , color) ;
193
191
}
194
192
out. write_str ( word) ;
195
- if concurrency == 1 u && term:: color_supported ( ) {
193
+ if use_color && term:: color_supported ( ) {
196
194
term:: reset ( out. get_buf_writer ( ) ) ;
197
195
}
198
196
}
199
197
}
200
198
199
+ fn use_color ( ) -> bool {
200
+ ret get_concurrency ( ) == 1 u;
201
+ }
202
+
203
+ tag testevent {
204
+ te_filtered( test_desc[ ] ) ;
205
+ te_result ( test_desc, test_result) ;
206
+ }
207
+
208
+ fn run_tests ( opts : & test_opts , tests : & test_desc [ ] ,
209
+ to_task : & test_to_task , callback : fn ( testevent ) ) {
210
+
211
+ let filtered_tests = filter_tests ( opts, tests) ;
212
+
213
+ callback ( te_filtered ( filtered_tests) ) ;
214
+
215
+ // It's tempting to just spawn all the tests at once but that doesn't
216
+ // provide a great user experience because you might sit waiting for the
217
+ // result of a particular test for an unusually long amount of time.
218
+ let concurrency = get_concurrency ( ) ;
219
+ log #fmt( "using %u test tasks" , concurrency) ;
220
+ let total = ivec:: len ( filtered_tests) ;
221
+ let run_idx = 0 u;
222
+ let wait_idx = 0 u;
223
+ let futures = ~[ ] ;
224
+
225
+ while wait_idx < total {
226
+ while ivec:: len ( futures) < concurrency && run_idx < total {
227
+ futures += ~[ run_test ( filtered_tests. ( run_idx) , to_task) ] ;
228
+ run_idx += 1 u;
229
+ }
230
+
231
+ let future = futures. ( 0 ) ;
232
+ let result = future. wait ( ) ;
233
+ callback ( te_result ( future. test , result) ) ;
234
+ futures = ivec:: slice ( futures, 1 u, ivec:: len ( futures) ) ;
235
+ wait_idx += 1 u;
236
+ }
237
+ }
238
+
201
239
fn get_concurrency ( ) -> uint {
202
240
alt getenv ( "RUST_THREADS" ) {
203
241
option:: some ( t) {
0 commit comments