Skip to content

Commit 7bde6c9

Browse files
testing: show extra information on failure
1 parent e6ef0ff commit 7bde6c9

File tree

1 file changed

+145
-8
lines changed

1 file changed

+145
-8
lines changed

plib/src/testing.rs

+145-8
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,154 @@ pub fn run_test_base(cmd: &str, args: &Vec<String>, stdin_data: &[u8]) -> Output
7979
}
8080

8181
pub fn run_test(plan: TestPlan) {
82-
let output = run_test_base(&plan.cmd, &plan.args, plan.stdin_data.as_bytes());
82+
use std::fmt::Write;
83+
84+
const LONG_MARKER: &str =
85+
"------------------------------------------------------------------------------------------------------------------------";
86+
const MARKER: &str =
87+
"--------------------------------------------------------------------------------";
88+
89+
let TestPlan {
90+
cmd,
91+
args,
92+
stdin_data,
93+
expected_out,
94+
expected_err,
95+
expected_exit_code,
96+
} = plan;
97+
98+
let output = run_test_base(&cmd, &args, stdin_data.as_bytes());
99+
100+
let Output {
101+
status,
102+
stdout,
103+
stderr,
104+
} = output;
105+
106+
let mut failures = Vec::<String>::new();
107+
108+
let stdout_cow = String::from_utf8_lossy(&stdout);
109+
110+
if stdout_cow != expected_out {
111+
failures.push(format!(
112+
"\
113+
stdout differs from what was expected
114+
{MARKER}
115+
116+
Actual
117+
{MARKER}
118+
{stdout_cow}
119+
{MARKER}
120+
121+
Expected
122+
{MARKER}
123+
{expected_out}
124+
{MARKER}
125+
"
126+
));
127+
}
83128

84-
let stdout = String::from_utf8_lossy(&output.stdout);
85-
assert_eq!(stdout, plan.expected_out);
129+
let stderr_cow = String::from_utf8_lossy(&stderr);
130+
131+
if stderr_cow != expected_err {
132+
failures.push(format!(
133+
"\
134+
stderr differs from what was expected
135+
{MARKER}
136+
137+
Actual
138+
{MARKER}
139+
{stderr_cow}
140+
{MARKER}
141+
142+
Expected
143+
{MARKER}
144+
{expected_err}
145+
{MARKER}
146+
"
147+
));
148+
}
86149

87-
let stderr = String::from_utf8_lossy(&output.stderr);
88-
assert_eq!(stderr, plan.expected_err);
150+
let status_code = status.code();
89151

90-
assert_eq!(output.status.code(), Some(plan.expected_exit_code));
91-
if plan.expected_exit_code == 0 {
92-
assert!(output.status.success());
152+
let expected_exit_code_option = Some(expected_exit_code);
153+
154+
if status_code != expected_exit_code_option {
155+
failures.push(format!(
156+
"\
157+
Exit status differs from what was expected
158+
{MARKER}
159+
160+
Actual
161+
{MARKER}
162+
{status_code:?}
163+
{MARKER}
164+
165+
Expected
166+
{MARKER}
167+
{expected_exit_code_option:?}
168+
{MARKER}
169+
"
170+
));
171+
}
172+
173+
if expected_exit_code == 0 && !status.success() {
174+
failures.push("Execution was expected to succeed, but it failed".to_owned());
175+
}
176+
177+
let failures_len = failures.len();
178+
179+
if failures_len > 0 {
180+
let mut buffer = String::with_capacity(4_096_usize);
181+
182+
let args_join = args.join(" ");
183+
184+
writeln!(
185+
&mut buffer,
186+
"\
187+
{LONG_MARKER}
188+
{MARKER}
189+
Test failed with {failures_len} total failure types
190+
{MARKER}
191+
192+
Command executed
193+
{MARKER}
194+
{cmd} {args_join}
195+
{MARKER}
196+
"
197+
)
198+
.unwrap();
199+
200+
for (us, st) in failures.iter().enumerate() {
201+
let failure_number = us + 1;
202+
203+
writeln!(
204+
&mut buffer,
205+
"Failure {failure_number} of {failures_len}: {st}"
206+
)
207+
.unwrap();
208+
}
209+
210+
let stderr_truncated = stderr_cow.chars().take(1_024_usize).collect::<String>();
211+
212+
writeln!(
213+
&mut buffer,
214+
"
215+
stderr, for diagnosing failure{}
216+
{MARKER}
217+
{stderr_cow}
218+
{MARKER}",
219+
if stderr_truncated.len() != stderr_cow.len() {
220+
" (truncated to 1 kibibyte)"
221+
} else {
222+
""
223+
}
224+
)
225+
.unwrap();
226+
227+
writeln!(&mut buffer, "{LONG_MARKER}").unwrap();
228+
229+
panic!("{buffer}");
93230
}
94231
}
95232

0 commit comments

Comments
 (0)