]>
git.proxmox.com Git - rustc.git/blob - src/libtest/formatters/terse.rs
1 // Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 pub(crate) struct TerseFormatter
<T
> {
14 out
: OutputLocation
<T
>,
16 is_multithreaded
: bool
,
17 /// Number of columns to fill when aligning names
23 impl<T
: Write
> TerseFormatter
<T
> {
25 out
: OutputLocation
<T
>,
28 is_multithreaded
: bool
,
39 pub fn write_ok(&mut self) -> io
::Result
<()> {
40 self.write_short_result(".", term
::color
::GREEN
)
43 pub fn write_failed(&mut self) -> io
::Result
<()> {
44 self.write_short_result("F", term
::color
::RED
)
47 pub fn write_ignored(&mut self) -> io
::Result
<()> {
48 self.write_short_result("i", term
::color
::YELLOW
)
51 pub fn write_allowed_fail(&mut self) -> io
::Result
<()> {
52 self.write_short_result("a", term
::color
::YELLOW
)
55 pub fn write_bench(&mut self) -> io
::Result
<()> {
56 self.write_pretty("bench", term
::color
::CYAN
)
59 pub fn write_short_result(
62 color
: term
::color
::Color
,
64 self.write_pretty(result
, color
)?
;
65 if self.test_count
% QUIET_MODE_MAX_COLUMN
== QUIET_MODE_MAX_COLUMN
- 1 {
66 // we insert a new line every 100 dots in order to flush the
67 // screen when dealing with line-buffered output (e.g. piping to
68 // `stamp` in the rust CI).
69 self.write_plain("\n")?
;
76 pub fn write_pretty(&mut self, word
: &str, color
: term
::color
::Color
) -> io
::Result
<()> {
78 Pretty(ref mut term
) => {
82 term
.write_all(word
.as_bytes())?
;
88 Raw(ref mut stdout
) => {
89 stdout
.write_all(word
.as_bytes())?
;
95 pub fn write_plain
<S
: AsRef
<str>>(&mut self, s
: S
) -> io
::Result
<()> {
97 self.out
.write_all(s
.as_bytes())?
;
101 pub fn write_outputs(&mut self, state
: &ConsoleTestState
) -> io
::Result
<()> {
102 self.write_plain("\nsuccesses:\n")?
;
103 let mut successes
= Vec
::new();
104 let mut stdouts
= String
::new();
105 for &(ref f
, ref stdout
) in &state
.not_failures
{
106 successes
.push(f
.name
.to_string());
107 if !stdout
.is_empty() {
108 stdouts
.push_str(&format
!("---- {} stdout ----\n\t", f
.name
));
109 let output
= String
::from_utf8_lossy(stdout
);
110 stdouts
.push_str(&output
);
111 stdouts
.push_str("\n");
114 if !stdouts
.is_empty() {
115 self.write_plain("\n")?
;
116 self.write_plain(&stdouts
)?
;
119 self.write_plain("\nsuccesses:\n")?
;
121 for name
in &successes
{
122 self.write_plain(&format
!(" {}\n", name
))?
;
127 pub fn write_failures(&mut self, state
: &ConsoleTestState
) -> io
::Result
<()> {
128 self.write_plain("\nfailures:\n")?
;
129 let mut failures
= Vec
::new();
130 let mut fail_out
= String
::new();
131 for &(ref f
, ref stdout
) in &state
.failures
{
132 failures
.push(f
.name
.to_string());
133 if !stdout
.is_empty() {
134 fail_out
.push_str(&format
!("---- {} stdout ----\n\t", f
.name
));
135 let output
= String
::from_utf8_lossy(stdout
);
136 fail_out
.push_str(&output
);
137 fail_out
.push_str("\n");
140 if !fail_out
.is_empty() {
141 self.write_plain("\n")?
;
142 self.write_plain(&fail_out
)?
;
145 self.write_plain("\nfailures:\n")?
;
147 for name
in &failures
{
148 self.write_plain(&format
!(" {}\n", name
))?
;
153 fn write_test_name(&mut self, desc
: &TestDesc
) -> io
::Result
<()> {
154 let name
= desc
.padded_name(self.max_name_len
, desc
.name
.padding());
155 self.write_plain(&format
!("test {} ... ", name
))?
;
161 impl<T
: Write
> OutputFormatter
for TerseFormatter
<T
> {
162 fn write_run_start(&mut self, test_count
: usize) -> io
::Result
<()> {
163 let noun
= if test_count
!= 1 { "tests" }
else { "test" }
;
164 self.write_plain(&format
!("\nrunning {} {}\n", test_count
, noun
))
167 fn write_test_start(&mut self, desc
: &TestDesc
) -> io
::Result
<()> {
168 // Remnants from old libtest code that used the padding value
169 // in order to indicate benchmarks.
170 // When running benchmarks, terse-mode should still print their name as if
171 // it is the Pretty formatter.
172 if !self.is_multithreaded
&& desc
.name
.padding() == PadOnRight
{
173 self.write_test_name(desc
)?
;
179 fn write_result(&mut self, desc
: &TestDesc
, result
: &TestResult
, _
: &[u8]) -> io
::Result
<()> {
181 TrOk
=> self.write_ok(),
182 TrFailed
| TrFailedMsg(_
) => self.write_failed(),
183 TrIgnored
=> self.write_ignored(),
184 TrAllowedFail
=> self.write_allowed_fail(),
186 if self.is_multithreaded
{
187 self.write_test_name(desc
)?
;
190 self.write_plain(&format
!(": {}\n", fmt_bench_samples(bs
)))
195 fn write_timeout(&mut self, desc
: &TestDesc
) -> io
::Result
<()> {
196 self.write_plain(&format
!(
197 "test {} has been running for over {} seconds\n",
198 desc
.name
, TEST_WARN_TIMEOUT_S
202 fn write_run_finish(&mut self, state
: &ConsoleTestState
) -> io
::Result
<bool
> {
203 if state
.options
.display_output
{
204 self.write_outputs(state
)?
;
206 let success
= state
.failed
== 0;
208 self.write_failures(state
)?
;
211 self.write_plain("\ntest result: ")?
;
214 // There's no parallelism at this point so it's safe to use color
215 self.write_pretty("ok", term
::color
::GREEN
)?
;
217 self.write_pretty("FAILED", term
::color
::RED
)?
;
220 let s
= if state
.allowed_fail
> 0 {
222 ". {} passed; {} failed ({} allowed); {} ignored; {} measured; {} filtered out\n\n",
224 state
.failed
+ state
.allowed_fail
,
232 ". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n",
233 state
.passed
, state
.failed
, state
.ignored
, state
.measured
, state
.filtered_out
237 self.write_plain(&s
)?
;