crate_compile_test/
error.rs

1use std::fmt;
2use std::path::PathBuf;
3
4use colored::*;
5use failure::Error;
6
7use formatting;
8use steps::check_errors::CompilerMessage;
9
10pub type Result<T> = ::std::result::Result<T, Error>;
11
12#[derive(Debug, Fail)]
13pub enum TestingError {
14    UnexpectedBuildSuccess,
15
16    CrateBuildFailed {
17        stdout: String,
18        stderr: String,
19    },
20
21    MessageExpectationsFailed {
22        unexpected: Vec<CompilerMessage>,
23        missing: Vec<CompilerMessage>,
24    },
25
26    TestFailed {
27        path: PathBuf,
28        error: Error,
29    },
30}
31
32struct ErrorDisplay<S1, S2>
33where
34    S1: AsRef<str>,
35    S2: AsRef<str>,
36{
37    header: S1,
38    content: Option<S2>,
39}
40
41impl fmt::Display for TestingError {
42    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
43        let display = match self {
44            TestingError::UnexpectedBuildSuccess => ErrorDisplay {
45                header: "Unexpectedly successful build!".into(),
46                content: None,
47            },
48
49            TestingError::TestFailed { path, error } => ErrorDisplay {
50                header: format!("{} failed:", path.to_string_lossy().bold().red()),
51                content: Some(formatting::prefix_each_line(error.to_string(), "  ")),
52            },
53
54            TestingError::CrateBuildFailed { stdout, stderr } => ErrorDisplay {
55                header: "Unable to build the crate!".into(),
56                content: Some({
57                    let mut output = String::new();
58
59                    if stdout.len() > 0 {
60                        output += &format!("\n{}", formatting::display_block("stdout", stdout));
61                    }
62
63                    if stderr.len() > 0 {
64                        output += &format!("\n{}", formatting::display_block("stderr", stderr));
65                    }
66
67                    output
68                }),
69            },
70
71            TestingError::MessageExpectationsFailed {
72                unexpected,
73                missing,
74            } => ErrorDisplay {
75                header: "Compiler messages don't fulfill expectations!".into(),
76                content: Some(format!(
77                    "\nUnexpected messages:\n{}\n\nMissing messages:\n{}",
78                    formatting::display_list(unexpected),
79                    formatting::display_list(missing)
80                )),
81            },
82        };
83
84        display.fmt(f)
85    }
86}
87
88impl<S1, S2> fmt::Display for ErrorDisplay<S1, S2>
89where
90    S1: AsRef<str>,
91    S2: AsRef<str>,
92{
93    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94        write!(f, "{}", self.header.as_ref())?;
95
96        if let Some(ref content) = self.content {
97            write!(f, "\n{}", content.as_ref())?;
98        }
99
100        Ok(())
101    }
102}