summaryrefslogtreecommitdiff
path: root/tests/porthole.rs
blob: 3efbffed89f9206777861008f98166dafe4bf177 (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
use std::cmp::Ordering;

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

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

enum Operator {
    Comment,
    Yes,
    No,
    Eq,
    Gt,
    Lt,
}

fn parse_operator<'a>() -> impl Parser<&'a str, Output = Operator> {
    let comment = tag("***").map(|_| Operator::Comment);
    let yes = tag("+").map(|_| Operator::Yes);
    let no = tag("-").map(|_| Operator::No);
    let eq = tag("=").map(|_| Operator::Eq);
    let gt = tag(">").map(|_| Operator::Gt);
    let lt = tag("<").map(|_| Operator::Lt);

    comment.or(yes).or(no).or(eq).or(gt).or(lt)
}

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

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

        match &operator {
            Operator::Comment => continue,
            Operator::Yes => {
                let a = Atom::parser()
                    .parse_finished(InputIter::new(
                        line.split_ascii_whitespace().nth(1).unwrap(),
                    ))
                    .unwrap();

                assert_eq!(
                    line.split_ascii_whitespace().nth(1).unwrap(),
                    &a.to_string()
                );
            }
            Operator::No => {
                assert!(
                    Atom::parser()
                        .parse_finished(InputIter::new(
                            line.split_ascii_whitespace().nth(1).unwrap()
                        ))
                        .is_err()
                );
            }
            Operator::Eq | 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::Eq => Ordering::Equal,
                        Operator::Gt => Ordering::Greater,
                        Operator::Lt => Ordering::Less,
                        _ => unreachable!(),
                    }
                );
            }
        }
    }
}