summaryrefslogtreecommitdiff
path: root/tests/porthole.rs
blob: 2c55ffeb6d851cd5be03dd8a57f68dfdde9ff6f3 (plain)
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use std::cmp::Ordering;

use gentoo_utils::{
    Parseable,
    atom::{Cp, Cpv},
};
use mon::{Parser, ParserIter, input::InputIter, tag};

static PORTHOLE_TXT: &'static str = include_str!(concat!(
    env!("CARGO_MANIFEST_DIR"),
    "/testdata/porthole.txt"
));

enum Operator {
    Cpv(bool),
    Cp(bool),
    Eq,
    Ne,
    Gt,
    Lt,
}

fn parse_operator<'a>() -> impl Parser<&'a str, Output = Operator> {
    let cpvyes = tag("cpv+").map(|_: &str| Operator::Cpv(true));
    let cpvno = tag("cpv-").map(|_: &str| Operator::Cpv(false));
    let cpyes = tag("cp+").map(|_| Operator::Cp(true));
    let cpno = tag("cp-").map(|_: &str| Operator::Cp(false));
    let eq = tag("=").map(|_| Operator::Eq);
    let ne = tag("!=").map(|_: &str| Operator::Ne);
    let gt = tag(">").map(|_| Operator::Gt);
    let lt = tag("<").map(|_| Operator::Lt);

    cpvyes
        .or(cpvno)
        .or(cpyes)
        .or(cpno)
        .or(eq)
        .or(ne)
        .or(gt)
        .or(lt)
}

#[test]
fn test_porthole() {
    for line in PORTHOLE_TXT.lines() {
        if line.is_empty() || line.starts_with("*") {
            continue;
        }

        let operator = parse_operator()
            .parse_finished(InputIter::new(
                line.split_ascii_whitespace().nth(0).unwrap(),
            ))
            .unwrap();

        match &operator {
            Operator::Cpv(is_err) => {
                let col = line.split_ascii_whitespace().nth(1).unwrap();

                let cpv = Cpv::parser().parse_finished(InputIter::new(col));

                match (dbg!(cpv), is_err) {
                    (Ok(cpv), true) => {
                        assert_eq!(&cpv.to_string(), col);
                    }
                    (Err(_), false) => (),
                    _ => {
                        panic!("{line}");
                    }
                };
            }

            Operator::Cp(is_err) => {
                let col = line.split_ascii_whitespace().nth(1).unwrap();

                let cp = Cp::parser().parse_finished(InputIter::new(col));

                match (cp, is_err) {
                    (Ok(cp), true) => {
                        assert_eq!(&cp.to_string(), col);
                    }
                    (Err(_), false) => (),
                    _ => {
                        panic!("{line}");
                    }
                };
            }

            Operator::Eq | Operator::Ne => {
                let a = Cpv::parser()
                    .parse_finished(InputIter::new(
                        line.split_ascii_whitespace().nth(1).unwrap(),
                    ))
                    .unwrap();

                let b = Cpv::parser()
                    .parse_finished(InputIter::new(
                        line.split_ascii_whitespace().nth(2).unwrap(),
                    ))
                    .unwrap();

                assert_eq!(
                    a.eq(&b),
                    match &operator {
                        Operator::Eq => true,
                        Operator::Ne => false,
                        _ => unreachable!(),
                    }
                );
            }

            Operator::Gt | Operator::Lt => {
                let a = Cpv::parser()
                    .parse_finished(InputIter::new(
                        line.split_ascii_whitespace().nth(1).unwrap(),
                    ))
                    .unwrap();

                let b = Cpv::parser()
                    .parse_finished(InputIter::new(
                        line.split_ascii_whitespace().nth(2).unwrap(),
                    ))
                    .unwrap();

                assert_eq!(
                    a.partial_cmp(&b).unwrap(),
                    match &operator {
                        Operator::Gt => Ordering::Greater,
                        Operator::Lt => Ordering::Less,
                        _ => unreachable!(),
                    }
                );
            }
        }
    }
}