Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
d24f9af3
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d24f9af3
编写于
11月 08, 2017
作者:
G
Gilad Naaman
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refactoring needed in order to have test json output.
上级
a97cd17f
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
308 addition
and
232 deletion
+308
-232
src/libtest/formatters.rs
src/libtest/formatters.rs
+246
-0
src/libtest/lib.rs
src/libtest/lib.rs
+62
-232
未找到文件。
src/libtest/formatters.rs
0 → 100644
浏览文件 @
d24f9af3
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
super
::
*
;
pub
(
crate
)
trait
OutputFormatter
{
fn
write_run_start
(
&
mut
self
,
len
:
usize
)
->
io
::
Result
<
()
>
;
fn
write_test_start
(
&
mut
self
,
test
:
&
TestDesc
,
align
:
NamePadding
,
max_name_len
:
usize
)
->
io
::
Result
<
()
>
;
fn
write_timeout
(
&
mut
self
,
desc
:
&
TestDesc
)
->
io
::
Result
<
()
>
;
fn
write_result
(
&
mut
self
,
result
:
&
TestResult
)
->
io
::
Result
<
()
>
;
fn
write_run_finish
(
&
mut
self
,
state
:
&
ConsoleTestState
)
->
io
::
Result
<
bool
>
;
}
pub
(
crate
)
struct
HumanFormatter
<
T
>
{
out
:
OutputLocation
<
T
>
,
terse
:
bool
,
use_color
:
bool
,
test_count
:
usize
,
}
impl
<
T
:
Write
>
HumanFormatter
<
T
>
{
pub
fn
new
(
out
:
OutputLocation
<
T
>
,
use_color
:
bool
,
terse
:
bool
)
->
Self
{
HumanFormatter
{
out
,
terse
,
use_color
,
test_count
:
0
,
}
}
#[cfg(test)]
pub
fn
output_location
(
&
self
)
->
&
OutputLocation
<
T
>
{
&
self
.out
}
pub
fn
write_ok
(
&
mut
self
)
->
io
::
Result
<
()
>
{
self
.write_short_result
(
"ok"
,
"."
,
term
::
color
::
GREEN
)
}
pub
fn
write_failed
(
&
mut
self
)
->
io
::
Result
<
()
>
{
self
.write_short_result
(
"FAILED"
,
"F"
,
term
::
color
::
RED
)
}
pub
fn
write_ignored
(
&
mut
self
)
->
io
::
Result
<
()
>
{
self
.write_short_result
(
"ignored"
,
"i"
,
term
::
color
::
YELLOW
)
}
pub
fn
write_allowed_fail
(
&
mut
self
)
->
io
::
Result
<
()
>
{
self
.write_short_result
(
"FAILED (allowed)"
,
"a"
,
term
::
color
::
YELLOW
)
}
pub
fn
write_bench
(
&
mut
self
)
->
io
::
Result
<
()
>
{
self
.write_pretty
(
"bench"
,
term
::
color
::
CYAN
)
}
pub
fn
write_short_result
(
&
mut
self
,
verbose
:
&
str
,
quiet
:
&
str
,
color
:
term
::
color
::
Color
)
->
io
::
Result
<
()
>
{
if
self
.terse
{
self
.write_pretty
(
quiet
,
color
)
?
;
if
self
.test_count
%
QUIET_MODE_MAX_COLUMN
==
QUIET_MODE_MAX_COLUMN
-
1
{
// we insert a new line every 100 dots in order to flush the
// screen when dealing with line-buffered output (e.g. piping to
// `stamp` in the rust CI).
self
.write_plain
(
"
\n
"
)
?
;
}
self
.test_count
+=
1
;
Ok
(())
}
else
{
self
.write_pretty
(
verbose
,
color
)
?
;
self
.write_plain
(
"
\n
"
)
}
}
pub
fn
write_pretty
(
&
mut
self
,
word
:
&
str
,
color
:
term
::
color
::
Color
)
->
io
::
Result
<
()
>
{
match
self
.out
{
Pretty
(
ref
mut
term
)
=>
{
if
self
.use_color
{
term
.fg
(
color
)
?
;
}
term
.write_all
(
word
.as_bytes
())
?
;
if
self
.use_color
{
term
.reset
()
?
;
}
term
.flush
()
}
Raw
(
ref
mut
stdout
)
=>
{
stdout
.write_all
(
word
.as_bytes
())
?
;
stdout
.flush
()
}
}
}
pub
fn
write_plain
<
S
:
AsRef
<
str
>>
(
&
mut
self
,
s
:
S
)
->
io
::
Result
<
()
>
{
let
s
=
s
.as_ref
();
self
.out
.write_all
(
s
.as_bytes
())
?
;
self
.out
.flush
()
}
pub
fn
write_outputs
(
&
mut
self
,
state
:
&
ConsoleTestState
)
->
io
::
Result
<
()
>
{
self
.write_plain
(
"
\n
successes:
\n
"
)
?
;
let
mut
successes
=
Vec
::
new
();
let
mut
stdouts
=
String
::
new
();
for
&
(
ref
f
,
ref
stdout
)
in
&
state
.not_failures
{
successes
.push
(
f
.name
.to_string
());
if
!
stdout
.is_empty
()
{
stdouts
.push_str
(
&
format!
(
"---- {} stdout ----
\n\t
"
,
f
.name
));
let
output
=
String
::
from_utf8_lossy
(
stdout
);
stdouts
.push_str
(
&
output
);
stdouts
.push_str
(
"
\n
"
);
}
}
if
!
stdouts
.is_empty
()
{
self
.write_plain
(
"
\n
"
)
?
;
self
.write_plain
(
&
stdouts
)
?
;
}
self
.write_plain
(
"
\n
successes:
\n
"
)
?
;
successes
.sort
();
for
name
in
&
successes
{
self
.write_plain
(
&
format!
(
" {}
\n
"
,
name
))
?
;
}
Ok
(())
}
pub
fn
write_failures
(
&
mut
self
,
state
:
&
ConsoleTestState
)
->
io
::
Result
<
()
>
{
self
.write_plain
(
"
\n
failures:
\n
"
)
?
;
let
mut
failures
=
Vec
::
new
();
let
mut
fail_out
=
String
::
new
();
for
&
(
ref
f
,
ref
stdout
)
in
&
state
.failures
{
failures
.push
(
f
.name
.to_string
());
if
!
stdout
.is_empty
()
{
fail_out
.push_str
(
&
format!
(
"---- {} stdout ----
\n\t
"
,
f
.name
));
let
output
=
String
::
from_utf8_lossy
(
stdout
);
fail_out
.push_str
(
&
output
);
fail_out
.push_str
(
"
\n
"
);
}
}
if
!
fail_out
.is_empty
()
{
self
.write_plain
(
"
\n
"
)
?
;
self
.write_plain
(
&
fail_out
)
?
;
}
self
.write_plain
(
"
\n
failures:
\n
"
)
?
;
failures
.sort
();
for
name
in
&
failures
{
self
.write_plain
(
&
format!
(
" {}
\n
"
,
name
))
?
;
}
Ok
(())
}
}
impl
<
T
:
Write
>
OutputFormatter
for
HumanFormatter
<
T
>
{
fn
write_run_start
(
&
mut
self
,
len
:
usize
)
->
io
::
Result
<
()
>
{
let
noun
=
if
len
!=
1
{
"tests"
}
else
{
"test"
};
self
.write_plain
(
&
format!
(
"
\n
running {} {}
\n
"
,
len
,
noun
))
}
fn
write_test_start
(
&
mut
self
,
test
:
&
TestDesc
,
align
:
NamePadding
,
max_name_len
:
usize
)
->
io
::
Result
<
()
>
{
if
self
.terse
&&
align
!=
PadOnRight
{
Ok
(())
}
else
{
let
name
=
test
.padded_name
(
max_name_len
,
align
);
self
.write_plain
(
&
format!
(
"test {} ... "
,
name
))
}
}
fn
write_result
(
&
mut
self
,
result
:
&
TestResult
)
->
io
::
Result
<
()
>
{
match
*
result
{
TrOk
=>
self
.write_ok
(),
TrFailed
|
TrFailedMsg
(
_
)
=>
self
.write_failed
(),
TrIgnored
=>
self
.write_ignored
(),
TrAllowedFail
=>
self
.write_allowed_fail
(),
TrBench
(
ref
bs
)
=>
{
self
.write_bench
()
?
;
self
.write_plain
(
&
format!
(
": {}
\n
"
,
fmt_bench_samples
(
bs
)))
}
}
}
fn
write_timeout
(
&
mut
self
,
desc
:
&
TestDesc
)
->
io
::
Result
<
()
>
{
self
.write_plain
(
&
format!
(
"test {} has been running for over {} seconds
\n
"
,
desc
.name
,
TEST_WARN_TIMEOUT_S
))
}
fn
write_run_finish
(
&
mut
self
,
state
:
&
ConsoleTestState
)
->
io
::
Result
<
bool
>
{
if
state
.options.display_output
{
self
.write_outputs
(
state
)
?
;
}
let
success
=
state
.failed
==
0
;
if
!
success
{
self
.write_failures
(
state
)
?
;
}
self
.write_plain
(
"
\n
test result: "
)
?
;
if
success
{
// There's no parallelism at this point so it's safe to use color
self
.write_pretty
(
"ok"
,
term
::
color
::
GREEN
)
?
;
}
else
{
self
.write_pretty
(
"FAILED"
,
term
::
color
::
RED
)
?
;
}
let
s
=
if
state
.allowed_fail
>
0
{
format!
(
". {} passed; {} failed ({} allowed); {} ignored; {} measured; {} filtered out
\n\n
"
,
state
.passed
,
state
.failed
+
state
.allowed_fail
,
state
.allowed_fail
,
state
.ignored
,
state
.measured
,
state
.filtered_out
)
}
else
{
format!
(
". {} passed; {} failed; {} ignored; {} measured; {} filtered out
\n\n
"
,
state
.passed
,
state
.failed
,
state
.ignored
,
state
.measured
,
state
.filtered_out
)
};
self
.write_plain
(
&
s
)
?
;
Ok
(
success
)
}
}
src/libtest/lib.rs
浏览文件 @
d24f9af3
...
...
@@ -84,6 +84,9 @@ pub mod test {
}
pub
mod
stats
;
mod
formatters
;
use
formatters
::
*
;
// The name of a test. By convention this follows the rules for rust
// paths; i.e. it should be a series of identifiers separated by double
...
...
@@ -359,7 +362,8 @@ fn optgroups() -> getopts::Options {
in parallel"
,
"n_threads"
)
.optmulti
(
""
,
"skip"
,
"Skip tests whose names contain FILTER (this flag can
\
be used multiple times)"
,
"FILTER"
)
.optflag
(
"q"
,
"quiet"
,
"Display one character per test instead of one line"
)
.optflag
(
"q"
,
"quiet"
,
"Display one character per test instead of one line.
\
Equivalent to --format=terse"
)
.optflag
(
""
,
"exact"
,
"Exactly match filters rather than by substring"
)
.optopt
(
""
,
"color"
,
"Configure coloring of output:
auto = colorize if stdout is a tty and tests are run on serially (default);
...
...
@@ -507,11 +511,24 @@ enum OutputLocation<T> {
Raw
(
T
),
}
struct
ConsoleTestState
<
T
>
{
impl
<
T
:
Write
>
Write
for
OutputLocation
<
T
>
{
fn
write
(
&
mut
self
,
buf
:
&
[
u8
])
->
io
::
Result
<
usize
>
{
match
*
self
{
Pretty
(
ref
mut
term
)
=>
term
.write
(
buf
),
Raw
(
ref
mut
stdout
)
=>
stdout
.write
(
buf
)
}
}
fn
flush
(
&
mut
self
)
->
io
::
Result
<
()
>
{
match
*
self
{
Pretty
(
ref
mut
term
)
=>
term
.flush
(),
Raw
(
ref
mut
stdout
)
=>
stdout
.flush
()
}
}
}
struct
ConsoleTestState
{
log_out
:
Option
<
File
>
,
out
:
OutputLocation
<
T
>
,
use_color
:
bool
,
quiet
:
bool
,
total
:
usize
,
passed
:
usize
,
failed
:
usize
,
...
...
@@ -526,22 +543,15 @@ struct ConsoleTestState<T> {
options
:
Options
,
}
impl
<
T
:
Write
>
ConsoleTestState
<
T
>
{
pub
fn
new
(
opts
:
&
TestOpts
,
_
:
Option
<
T
>
)
->
io
::
Result
<
ConsoleTestState
<
io
::
Stdout
>
>
{
impl
ConsoleTestState
{
pub
fn
new
(
opts
:
&
TestOpts
)
->
io
::
Result
<
ConsoleTestState
>
{
let
log_out
=
match
opts
.logfile
{
Some
(
ref
path
)
=>
Some
(
File
::
create
(
path
)
?
),
None
=>
None
,
};
let
out
=
match
term
::
stdout
()
{
None
=>
Raw
(
io
::
stdout
()),
Some
(
t
)
=>
Pretty
(
t
),
};
Ok
(
ConsoleTestState
{
out
,
log_out
,
use_color
:
use_color
(
opts
),
quiet
:
opts
.quiet
,
total
:
0
,
passed
:
0
,
failed
:
0
,
...
...
@@ -557,114 +567,6 @@ pub fn new(opts: &TestOpts, _: Option<T>) -> io::Result<ConsoleTestState<io::Std
})
}
pub
fn
write_ok
(
&
mut
self
)
->
io
::
Result
<
()
>
{
self
.write_short_result
(
"ok"
,
"."
,
term
::
color
::
GREEN
)
}
pub
fn
write_failed
(
&
mut
self
)
->
io
::
Result
<
()
>
{
self
.write_short_result
(
"FAILED"
,
"F"
,
term
::
color
::
RED
)
}
pub
fn
write_ignored
(
&
mut
self
)
->
io
::
Result
<
()
>
{
self
.write_short_result
(
"ignored"
,
"i"
,
term
::
color
::
YELLOW
)
}
pub
fn
write_allowed_fail
(
&
mut
self
)
->
io
::
Result
<
()
>
{
self
.write_short_result
(
"FAILED (allowed)"
,
"a"
,
term
::
color
::
YELLOW
)
}
pub
fn
write_bench
(
&
mut
self
)
->
io
::
Result
<
()
>
{
self
.write_pretty
(
"bench"
,
term
::
color
::
CYAN
)
}
pub
fn
write_short_result
(
&
mut
self
,
verbose
:
&
str
,
quiet
:
&
str
,
color
:
term
::
color
::
Color
)
->
io
::
Result
<
()
>
{
if
self
.quiet
{
self
.write_pretty
(
quiet
,
color
)
?
;
if
self
.current_test_count
()
%
QUIET_MODE_MAX_COLUMN
==
QUIET_MODE_MAX_COLUMN
-
1
{
// we insert a new line every 100 dots in order to flush the
// screen when dealing with line-buffered output (e.g. piping to
// `stamp` in the rust CI).
self
.write_plain
(
"
\n
"
)
?
;
}
Ok
(())
}
else
{
self
.write_pretty
(
verbose
,
color
)
?
;
self
.write_plain
(
"
\n
"
)
}
}
pub
fn
write_pretty
(
&
mut
self
,
word
:
&
str
,
color
:
term
::
color
::
Color
)
->
io
::
Result
<
()
>
{
match
self
.out
{
Pretty
(
ref
mut
term
)
=>
{
if
self
.use_color
{
term
.fg
(
color
)
?
;
}
term
.write_all
(
word
.as_bytes
())
?
;
if
self
.use_color
{
term
.reset
()
?
;
}
term
.flush
()
}
Raw
(
ref
mut
stdout
)
=>
{
stdout
.write_all
(
word
.as_bytes
())
?
;
stdout
.flush
()
}
}
}
pub
fn
write_plain
<
S
:
AsRef
<
str
>>
(
&
mut
self
,
s
:
S
)
->
io
::
Result
<
()
>
{
let
s
=
s
.as_ref
();
match
self
.out
{
Pretty
(
ref
mut
term
)
=>
{
term
.write_all
(
s
.as_bytes
())
?
;
term
.flush
()
}
Raw
(
ref
mut
stdout
)
=>
{
stdout
.write_all
(
s
.as_bytes
())
?
;
stdout
.flush
()
}
}
}
pub
fn
write_run_start
(
&
mut
self
,
len
:
usize
)
->
io
::
Result
<
()
>
{
self
.total
=
len
;
let
noun
=
if
len
!=
1
{
"tests"
}
else
{
"test"
};
self
.write_plain
(
&
format!
(
"
\n
running {} {}
\n
"
,
len
,
noun
))
}
pub
fn
write_test_start
(
&
mut
self
,
test
:
&
TestDesc
,
align
:
NamePadding
)
->
io
::
Result
<
()
>
{
if
self
.quiet
&&
align
!=
PadOnRight
{
Ok
(())
}
else
{
let
name
=
test
.padded_name
(
self
.max_name_len
,
align
);
self
.write_plain
(
&
format!
(
"test {} ... "
,
name
))
}
}
pub
fn
write_result
(
&
mut
self
,
result
:
&
TestResult
)
->
io
::
Result
<
()
>
{
match
*
result
{
TrOk
=>
self
.write_ok
(),
TrFailed
|
TrFailedMsg
(
_
)
=>
self
.write_failed
(),
TrIgnored
=>
self
.write_ignored
(),
TrAllowedFail
=>
self
.write_allowed_fail
(),
TrBench
(
ref
bs
)
=>
{
self
.write_bench
()
?
;
self
.write_plain
(
&
format!
(
": {}
\n
"
,
fmt_bench_samples
(
bs
)))
}
}
}
pub
fn
write_timeout
(
&
mut
self
,
desc
:
&
TestDesc
)
->
io
::
Result
<
()
>
{
self
.write_plain
(
&
format!
(
"test {} has been running for over {} seconds
\n
"
,
desc
.name
,
TEST_WARN_TIMEOUT_S
))
}
pub
fn
write_log
<
S
:
AsRef
<
str
>>
(
&
mut
self
,
msg
:
S
)
->
io
::
Result
<
()
>
{
let
msg
=
msg
.as_ref
();
match
self
.log_out
{
...
...
@@ -687,101 +589,9 @@ pub fn write_log_result(&mut self, test: &TestDesc, result: &TestResult) -> io::
test
.name
))
}
pub
fn
write_failures
(
&
mut
self
)
->
io
::
Result
<
()
>
{
self
.write_plain
(
"
\n
failures:
\n
"
)
?
;
let
mut
failures
=
Vec
::
new
();
let
mut
fail_out
=
String
::
new
();
for
&
(
ref
f
,
ref
stdout
)
in
&
self
.failures
{
failures
.push
(
f
.name
.to_string
());
if
!
stdout
.is_empty
()
{
fail_out
.push_str
(
&
format!
(
"---- {} stdout ----
\n\t
"
,
f
.name
));
let
output
=
String
::
from_utf8_lossy
(
stdout
);
fail_out
.push_str
(
&
output
);
fail_out
.push_str
(
"
\n
"
);
}
}
if
!
fail_out
.is_empty
()
{
self
.write_plain
(
"
\n
"
)
?
;
self
.write_plain
(
&
fail_out
)
?
;
}
self
.write_plain
(
"
\n
failures:
\n
"
)
?
;
failures
.sort
();
for
name
in
&
failures
{
self
.write_plain
(
&
format!
(
" {}
\n
"
,
name
))
?
;
}
Ok
(())
}
pub
fn
write_outputs
(
&
mut
self
)
->
io
::
Result
<
()
>
{
self
.write_plain
(
"
\n
successes:
\n
"
)
?
;
let
mut
successes
=
Vec
::
new
();
let
mut
stdouts
=
String
::
new
();
for
&
(
ref
f
,
ref
stdout
)
in
&
self
.not_failures
{
successes
.push
(
f
.name
.to_string
());
if
!
stdout
.is_empty
()
{
stdouts
.push_str
(
&
format!
(
"---- {} stdout ----
\n\t
"
,
f
.name
));
let
output
=
String
::
from_utf8_lossy
(
stdout
);
stdouts
.push_str
(
&
output
);
stdouts
.push_str
(
"
\n
"
);
}
}
if
!
stdouts
.is_empty
()
{
self
.write_plain
(
"
\n
"
)
?
;
self
.write_plain
(
&
stdouts
)
?
;
}
self
.write_plain
(
"
\n
successes:
\n
"
)
?
;
successes
.sort
();
for
name
in
&
successes
{
self
.write_plain
(
&
format!
(
" {}
\n
"
,
name
))
?
;
}
Ok
(())
}
fn
current_test_count
(
&
self
)
->
usize
{
self
.passed
+
self
.failed
+
self
.ignored
+
self
.measured
+
self
.allowed_fail
}
pub
fn
write_run_finish
(
&
mut
self
)
->
io
::
Result
<
bool
>
{
assert
!
(
self
.current_test_count
()
==
self
.total
);
if
self
.options.display_output
{
self
.write_outputs
()
?
;
}
let
success
=
self
.failed
==
0
;
if
!
success
{
self
.write_failures
()
?
;
}
self
.write_plain
(
"
\n
test result: "
)
?
;
if
success
{
// There's no parallelism at this point so it's safe to use color
self
.write_pretty
(
"ok"
,
term
::
color
::
GREEN
)
?
;
}
else
{
self
.write_pretty
(
"FAILED"
,
term
::
color
::
RED
)
?
;
}
let
s
=
if
self
.allowed_fail
>
0
{
format!
(
". {} passed; {} failed ({} allowed); {} ignored; {} measured; {} filtered out
\n\n
"
,
self
.passed
,
self
.failed
+
self
.allowed_fail
,
self
.allowed_fail
,
self
.ignored
,
self
.measured
,
self
.filtered_out
)
}
else
{
format!
(
". {} passed; {} failed; {} ignored; {} measured; {} filtered out
\n\n
"
,
self
.passed
,
self
.failed
,
self
.ignored
,
self
.measured
,
self
.filtered_out
)
};
self
.write_plain
(
&
s
)
?
;
return
Ok
(
success
);
}
}
// Format a number with thousands separators
...
...
@@ -827,7 +637,12 @@ pub fn fmt_bench_samples(bs: &BenchSamples) -> String {
// List the tests to console, and optionally to logfile. Filters are honored.
pub
fn
list_tests_console
(
opts
:
&
TestOpts
,
tests
:
Vec
<
TestDescAndFn
>
)
->
io
::
Result
<
()
>
{
let
mut
st
=
ConsoleTestState
::
new
(
opts
,
None
::
<
io
::
Stdout
>
)
?
;
let
output
=
match
term
::
stdout
()
{
None
=>
Raw
(
io
::
stdout
()),
Some
(
t
)
=>
Pretty
(
t
),
};
let
mut
out
=
HumanFormatter
::
new
(
output
,
use_color
(
opts
),
opts
.quiet
);
let
mut
st
=
ConsoleTestState
::
new
(
opts
)
?
;
let
mut
ntest
=
0
;
let
mut
nbench
=
0
;
...
...
@@ -842,7 +657,7 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Res
StaticBenchFn
(
..
)
|
DynBenchFn
(
..
)
=>
{
nbench
+=
1
;
"benchmark"
},
};
s
t
.write_plain
(
format!
(
"{}: {}
\n
"
,
name
,
fntype
))
?
;
ou
t
.write_plain
(
format!
(
"{}: {}
\n
"
,
name
,
fntype
))
?
;
st
.write_log
(
format!
(
"{} {}
\n
"
,
fntype
,
name
))
?
;
}
...
...
@@ -868,15 +683,21 @@ fn plural(count: u32, s: &str) -> String {
// A simple console test runner
pub
fn
run_tests_console
(
opts
:
&
TestOpts
,
tests
:
Vec
<
TestDescAndFn
>
)
->
io
::
Result
<
bool
>
{
fn
callback
<
T
:
Write
>
(
event
:
&
TestEvent
,
st
:
&
mut
ConsoleTestState
<
T
>
)
->
io
::
Result
<
()
>
{
fn
callback
(
event
:
&
TestEvent
,
st
:
&
mut
ConsoleTestState
,
out
:
&
mut
OutputFormatter
)
->
io
::
Result
<
()
>
{
match
(
*
event
)
.clone
()
{
TeFiltered
(
ref
filtered_tests
)
=>
st
.write_run_start
(
filtered_tests
.len
()),
TeFiltered
(
ref
filtered_tests
)
=>
{
st
.total
=
filtered_tests
.len
();
out
.write_run_start
(
filtered_tests
.len
())
},
TeFilteredOut
(
filtered_out
)
=>
Ok
(
st
.filtered_out
=
filtered_out
),
TeWait
(
ref
test
,
padding
)
=>
st
.write_test_start
(
test
,
padding
),
TeTimeout
(
ref
test
)
=>
s
t
.write_timeout
(
test
),
TeWait
(
ref
test
,
padding
)
=>
out
.write_test_start
(
test
,
padding
,
st
.max_name_len
),
TeTimeout
(
ref
test
)
=>
ou
t
.write_timeout
(
test
),
TeResult
(
test
,
result
,
stdout
)
=>
{
st
.write_log_result
(
&
test
,
&
result
)
?
;
s
t
.write_result
(
&
result
)
?
;
ou
t
.write_result
(
&
result
)
?
;
match
result
{
TrOk
=>
{
st
.passed
+=
1
;
...
...
@@ -908,7 +729,14 @@ fn callback<T: Write>(event: &TestEvent, st: &mut ConsoleTestState<T>) -> io::Re
}
}
let
mut
st
=
ConsoleTestState
::
new
(
opts
,
None
::
<
io
::
Stdout
>
)
?
;
let
output
=
match
term
::
stdout
()
{
None
=>
Raw
(
io
::
stdout
()),
Some
(
t
)
=>
Pretty
(
t
),
};
let
mut
out
=
HumanFormatter
::
new
(
output
,
use_color
(
opts
),
opts
.quiet
);
let
mut
st
=
ConsoleTestState
::
new
(
opts
)
?
;
fn
len_if_padded
(
t
:
&
TestDescAndFn
)
->
usize
{
match
t
.testfn
.padding
()
{
PadNone
=>
0
,
...
...
@@ -919,8 +747,11 @@ fn len_if_padded(t: &TestDescAndFn) -> usize {
let
n
=
t
.desc.name
.as_slice
();
st
.max_name_len
=
n
.len
();
}
run_tests
(
opts
,
tests
,
|
x
|
callback
(
&
x
,
&
mut
st
))
?
;
return
st
.write_run_finish
();
run_tests
(
opts
,
tests
,
|
x
|
callback
(
&
x
,
&
mut
st
,
&
mut
out
))
?
;
assert
!
(
st
.current_test_count
()
==
st
.total
);
return
out
.write_run_finish
(
&
st
);
}
#[test]
...
...
@@ -939,11 +770,10 @@ fn should_sort_failures_before_printing_them() {
allow_fail
:
false
,
};
let
mut
st
=
ConsoleTestState
{
let
mut
out
=
HumanFormatter
::
new
(
Raw
(
Vec
::
new
()),
false
,
false
);
let
st
=
ConsoleTestState
{
log_out
:
None
,
out
:
Raw
(
Vec
::
new
()),
use_color
:
false
,
quiet
:
false
,
total
:
0
,
passed
:
0
,
failed
:
0
,
...
...
@@ -958,10 +788,10 @@ fn should_sort_failures_before_printing_them() {
not_failures
:
Vec
::
new
(),
};
st
.write_failures
(
)
.unwrap
();
let
s
=
match
st
.out
{
Raw
(
ref
m
)
=>
String
::
from_utf8_lossy
(
&
m
[
..
]),
Pretty
(
_
)
=>
unreachable!
(),
out
.write_failures
(
&
st
)
.unwrap
();
let
s
=
match
out
.output_location
()
{
&
Raw
(
ref
m
)
=>
String
::
from_utf8_lossy
(
&
m
[
..
]),
&
Pretty
(
_
)
=>
unreachable!
(),
};
let
apos
=
s
.find
(
"a"
)
.unwrap
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录