json_pop/extra/
test_utils.rs

1#[cfg(test)]
2use crate::{error, parser, extra::source, extra::source::Parsable as _, value};
3
4#[cfg(not(test))]
5use crate::extra::never;
6
7#[derive(Debug)]
8#[cfg(test)]
9pub enum TestError<'a> {
10    InvalidSourceParsedOk(value::Value<'a>, &'a source::Source<'a>),
11}
12#[cfg(not(test))]
13pub type TestError<'a> = never::Never<'a>;
14
15#[cfg(test)]
16pub enum Test<'a> {
17    TestValid(source::Source<'a>),
18    TestInvalid(source::Source<'a>),
19}
20
21#[cfg(test)]
22impl<'a> Test<'a> {
23    pub fn should_fail(&self) -> bool {
24        match self {
25            Self::TestValid(_) => false,
26            Self::TestInvalid(_) => true,
27        }
28    }
29}
30
31#[cfg(test)]
32impl<'a> source::Parsable<'a> for Test<'a> {
33    fn parse(&'a self) -> parser::Parsed<'a> {
34        match self {
35            Test::TestValid(src) | Test::TestInvalid(src) => src.parse(),
36        }
37    }
38
39    fn source(&'a self) -> &'a source::Source<'a> {
40        match self {
41            Self::TestValid(source) | Self::TestInvalid(source) => source,
42        }
43    }
44}
45
46#[cfg(test)]
47impl<'a> source::ErrorHandling<'a> for Test<'a> {
48    #[cfg(not(feature = "pretty_errors"))]
49    fn handle_errors(
50        &'a self,
51        parsed: parser::Parsed<'a>,
52    ) -> Result<value::Value<'a>, error::JsonPopError<'a>> {
53        match (parsed.0.is_err(), self.should_fail()) {
54            (true, true) => {
55                eprint!("{:#?}", parsed);
56                return Ok(value::Value::Null);
57            }
58            (false, true) => Err(error::JsonPopError::TestError(
59                TestError::InvalidSourceParsedOk(parsed.0.unwrap(), self.source()),
60            )),
61            (_, _) => Ok(parsed.0.map_err(error::JsonPopError::Parse)?),
62        }
63    }
64
65    #[cfg(feature = "pretty_errors")]
66    fn handle_errors(
67        &'a self,
68        parsed: parser::Parsed<'a>,
69    ) -> Result<value::Value<'a>, error::JsonPopError<'a>> {
70        if let Err(error) = parsed.0 {
71            let mut writer = codespan_reporting::term::termcolor::Buffer::no_color();
72            let config = codespan_reporting::term::Config::default();
73            let (files, diagnostic) =
74                crate::extra::codespan::from_parse_error("stdin", self.source(), &error);
75
76            let () = codespan_reporting::term::emit(&mut writer, &config, &files, &diagnostic)?;
77            eprint!("{}", std::str::from_utf8(writer.as_slice()).unwrap());
78            if self.should_fail() {
79                Ok(value::Value::Null)
80            } else {
81                Err(crate::error::JsonPopError::Parse(error))
82            }
83        } else {
84            if self.should_fail() {
85                return Err(error::JsonPopError::TestError(
86                    TestError::InvalidSourceParsedOk(parsed.0.unwrap(), self.source()),
87                ));
88            }
89            parsed.0.map_err(crate::error::JsonPopError::Parse)
90        }
91    }
92}