1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
mod result;
#[cfg(test)]
pub(crate) mod testing;

pub(crate) use self::result::TestInputType;
pub use self::result::TestResult;
#[cfg(test)]
pub use self::testing::TestContext;

use crate::{check::Checker, common::*, parse};

/// This struct represents a single FileCheck test which
/// can be run against one or more input files for verification.
///
/// This is the primary entrypoint for running FileCheck tests.
pub struct Test<'a> {
    config: &'a Config,
    strings: StringInterner,
    match_file: ArcSource,
}
impl<'a> Test<'a> {
    /// Create a new test from the given match file (containing CHECKs) and configuration
    ///
    /// This function does not compile the actual test file until verification is requested.
    pub fn new<S>(match_file: S, config: &'a Config) -> Self
    where
        ArcSource: From<S>,
    {
        Self {
            config,
            match_file: ArcSource::from(match_file),
            strings: StringInterner::new(),
        }
    }

    /// Verify the given input file passes this test.
    ///
    /// First, it parses the check file for rules, post-processes them, and then
    /// applies the parsed rules to the input file, to determine if the file matches
    /// or fails to match.
    pub fn verify<'input, S>(&mut self, input_file: S) -> DiagResult<Vec<MatchInfo<'static>>>
    where
        ArcSource: From<S> + 'input,
    {
        // Parse the check file
        let mut parser = parse::CheckFileParser::new(&self.config, &mut self.strings);

        let match_file = parser
            .parse(&self.match_file)
            .map_err(|err| Report::new(err).with_source_code(self.match_file.clone()))?;

        // Compile the check rules, and raise an error if any are invalid
        let program = match_file.compile(self.config, &mut self.strings)?;

        // Apply the checks
        let mut checker = Checker::new(
            self.config,
            &mut self.strings,
            program,
            self.match_file.clone(),
        );
        checker
            .check_input(ArcSource::from(input_file))
            .into_result()
            .map_err(Report::new)
    }
}